From 1042941fa87fd9475faf52a844e46f9fd0e1d5be Mon Sep 17 00:00:00 2001 From: El De-dog-lo <3859395+fubuloubu@users.noreply.github.com> Date: Wed, 2 Nov 2022 21:14:06 -0400 Subject: [PATCH 1/8] fix: run gas report --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 886b243..d869f54 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -9,4 +9,4 @@ jobs: - uses: actions/checkout@v2 - uses: ApeWorX/github-action@v1 - run: ape compile --size - - run: ape test -s + - run: ape test -s --gas From b70a8e8aed4627d93eceb57343d380509fa068a9 Mon Sep 17 00:00:00 2001 From: fubuloubu <3859395+fubuloubu@users.noreply.github.com> Date: Tue, 25 Jul 2023 16:32:45 -0400 Subject: [PATCH 2/8] chore: upgrade Ape to 0.6.x series --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index adca816..f2447d1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -eth-ape>=0.5.4 +eth-ape>=0.6 black jsbeautifier From 9849ae159d8c757b88b36b842b79ba238cd30822 Mon Sep 17 00:00:00 2001 From: fubuloubu <3859395+fubuloubu@users.noreply.github.com> Date: Tue, 25 Jul 2023 16:37:15 -0400 Subject: [PATCH 3/8] refactor: upgrade to OZ 4.8.0, which contains ERC4626 interface --- ape-config.yaml | 4 ++-- contracts/ERC4626.sol | 20 -------------------- contracts/SolidityVault.sol | 2 +- 3 files changed, 3 insertions(+), 23 deletions(-) delete mode 100644 contracts/ERC4626.sol diff --git a/ape-config.yaml b/ape-config.yaml index 00426e8..d4c07ff 100644 --- a/ape-config.yaml +++ b/ape-config.yaml @@ -5,11 +5,11 @@ plugins: dependencies: - name: OpenZeppelin github: OpenZeppelin/openzeppelin-contracts - version: 4.7.3 + version: 4.8.0 solidity: import_remapping: - - "@OpenZeppelin=OpenZeppelin/4.7.3" + - "@OpenZeppelin=OpenZeppelin/4.8.0" test: gas: diff --git a/contracts/ERC4626.sol b/contracts/ERC4626.sol deleted file mode 100644 index cf99027..0000000 --- a/contracts/ERC4626.sol +++ /dev/null @@ -1,20 +0,0 @@ -interface IERC4626 { - function asset() external view returns (address assetTokenAddress); - function totalAssets() external view returns (uint256 totalManagedAssets); - function convertToShares(uint256 assets) external view returns (uint256 shares); - function convertToAssets(uint256 shares) external view returns (uint256 assets); - function maxDeposit(address receiver) external view returns (uint256 maxAssets); - function previewDeposit(uint256 assets) external view returns (uint256 shares); - function deposit(uint256 assets, address receiver) external returns (uint256 shares); - function maxMint(address receiver) external view returns (uint256 maxShares); - function previewMint(uint256 shares) external view returns (uint256 assets); - function mint(uint256 shares, address receiver) external returns (uint256 assets); - function maxWithdraw(address owner) external view returns (uint256 maxAssets); - function previewWithdraw(uint256 assets) external view returns (uint256 shares); - function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); - function maxRedeem(address owner) external view returns (uint256 maxShares); - function previewRedeem(uint256 shares) external view returns (uint256 assets); - function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); - event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares); - event Withdraw(address indexed caller, address indexed receiver, address indexed owner, uint256 assets, uint256 shares); -} diff --git a/contracts/SolidityVault.sol b/contracts/SolidityVault.sol index 954adf2..09d4a42 100644 --- a/contracts/SolidityVault.sol +++ b/contracts/SolidityVault.sol @@ -1,6 +1,6 @@ pragma solidity ^0.8; -import { IERC4626 } from "ERC4626.sol"; +import { IERC4626 } from "@OpenZeppelin/interfaces/IERC4626.sol"; import { ERC20 } from "@OpenZeppelin/token/ERC20/ERC20.sol"; contract SolidityVault is IERC4626, ERC20 { From 1dbb114d29db21412e6760435b3e9d507b37de80 Mon Sep 17 00:00:00 2001 From: fubuloubu <3859395+fubuloubu@users.noreply.github.com> Date: Tue, 25 Jul 2023 16:38:28 -0400 Subject: [PATCH 4/8] refactor: upgrade to Vyper 0.3.9 --- contracts/VyperVault.vy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/VyperVault.vy b/contracts/VyperVault.vy index 5f56ebd..4e31397 100644 --- a/contracts/VyperVault.vy +++ b/contracts/VyperVault.vy @@ -1,4 +1,4 @@ -# @version 0.3.2 +# @version 0.3.9 from vyper.interfaces import ERC20 import ERC4626 as ERC4626 From 33e1e56ee7b1760ed6cb0d503d6bc63deef9a172 Mon Sep 17 00:00:00 2001 From: fubuloubu <3859395+fubuloubu@users.noreply.github.com> Date: Tue, 25 Jul 2023 17:05:50 -0400 Subject: [PATCH 5/8] style: black update --- tests/test_methods.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/test_methods.py b/tests/test_methods.py index c7ccf79..898c4cb 100644 --- a/tests/test_methods.py +++ b/tests/test_methods.py @@ -1,4 +1,4 @@ -AMOUNT = 100 * 10 ** 18 +AMOUNT = 100 * 10**18 def test_asset(vault, token): @@ -8,18 +8,18 @@ def test_asset(vault, token): def test_max_methods(accounts, vault): a = accounts[0] - assert vault.maxDeposit(a) == 2 ** 256 - 1 - assert vault.maxMint(a) == 2 ** 256 - 1 - assert vault.maxWithdraw(a) == 2 ** 256 - 1 - assert vault.maxRedeem(a) == 2 ** 256 - 1 + assert vault.maxDeposit(a) == 2**256 - 1 + assert vault.maxMint(a) == 2**256 - 1 + assert vault.maxWithdraw(a) == 2**256 - 1 + assert vault.maxRedeem(a) == 2**256 - 1 def test_preview_methods(accounts, token, vault): a = accounts[0] assert vault.totalAssets() == 0 - assert vault.convertToAssets(10 ** 18) == 0 # no assets - assert vault.convertToShares(10 ** 18) == 10 ** 18 # 1:1 price + assert vault.convertToAssets(10**18) == 0 # no assets + assert vault.convertToShares(10**18) == 10**18 # 1:1 price assert vault.previewDeposit(AMOUNT) == AMOUNT # 1:1 price assert vault.previewMint(AMOUNT) == AMOUNT # 1:1 price assert vault.previewWithdraw(AMOUNT) == 0 # but no assets @@ -30,8 +30,8 @@ def test_preview_methods(accounts, token, vault): vault.deposit(AMOUNT, sender=a) assert vault.totalAssets() == AMOUNT - assert vault.convertToAssets(10 ** 18) == 10 ** 18 # 1:1 price - assert vault.convertToShares(10 ** 18) == 10 ** 18 # 1:1 price + assert vault.convertToAssets(10**18) == 10**18 # 1:1 price + assert vault.convertToShares(10**18) == 10**18 # 1:1 price assert vault.previewDeposit(AMOUNT) == AMOUNT # 1:1 price assert vault.previewMint(AMOUNT) == AMOUNT # 1:1 price assert vault.previewWithdraw(AMOUNT) == AMOUNT # 1:1 price @@ -40,8 +40,8 @@ def test_preview_methods(accounts, token, vault): token.DEBUG_mint(vault, AMOUNT, sender=a) assert vault.totalAssets() == 2 * AMOUNT - assert vault.convertToAssets(10 ** 18) == 2 * 10 ** 18 # 2:1 price - assert vault.convertToShares(2 * 10 ** 18) == 10 ** 18 # 2:1 price + assert vault.convertToAssets(10**18) == 2 * 10**18 # 2:1 price + assert vault.convertToShares(2 * 10**18) == 10**18 # 2:1 price assert vault.previewDeposit(AMOUNT) == AMOUNT // 2 # 2:1 price assert vault.previewMint(AMOUNT // 2) == AMOUNT # 2:1 price assert vault.previewWithdraw(AMOUNT) == AMOUNT // 2 # 2:1 price @@ -50,8 +50,8 @@ def test_preview_methods(accounts, token, vault): vault.DEBUG_steal_tokens(AMOUNT, sender=a) assert vault.totalAssets() == AMOUNT - assert vault.convertToAssets(10 ** 18) == 10 ** 18 # 1:1 price - assert vault.convertToShares(10 ** 18) == 10 ** 18 # 1:1 price + assert vault.convertToAssets(10**18) == 10**18 # 1:1 price + assert vault.convertToShares(10**18) == 10**18 # 1:1 price assert vault.previewDeposit(AMOUNT) == AMOUNT # 1:1 price assert vault.previewMint(AMOUNT) == AMOUNT # 1:1 price assert vault.previewWithdraw(AMOUNT) == AMOUNT # 1:1 price @@ -60,8 +60,8 @@ def test_preview_methods(accounts, token, vault): vault.DEBUG_steal_tokens(AMOUNT // 2, sender=a) assert vault.totalAssets() == AMOUNT // 2 - assert vault.convertToAssets(10 ** 18) == 10 ** 18 // 2 # 1:2 price - assert vault.convertToShares(10 ** 18 // 2) == 10 ** 18 # 1:2 price + assert vault.convertToAssets(10**18) == 10**18 // 2 # 1:2 price + assert vault.convertToShares(10**18 // 2) == 10**18 # 1:2 price assert vault.previewDeposit(AMOUNT) == 2 * AMOUNT # 1:2 price assert vault.previewMint(2 * AMOUNT) == AMOUNT # 1:2 price assert vault.previewWithdraw(AMOUNT) == 2 * AMOUNT # 1:2 price From c7c0f129f566acfcf2be87b9ed23821b1077abaf Mon Sep 17 00:00:00 2001 From: fubuloubu <3859395+fubuloubu@users.noreply.github.com> Date: Tue, 25 Jul 2023 17:06:07 -0400 Subject: [PATCH 6/8] test: show events are emitted --- tests/test_methods.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/test_methods.py b/tests/test_methods.py index 898c4cb..ecf1455 100644 --- a/tests/test_methods.py +++ b/tests/test_methods.py @@ -1,4 +1,5 @@ AMOUNT = 100 * 10**18 +from ape.utils import ZERO_ADDRESS def test_asset(vault, token): @@ -27,7 +28,13 @@ def test_preview_methods(accounts, token, vault): token.DEBUG_mint(a, AMOUNT, sender=a) token.approve(vault, AMOUNT, sender=a) - vault.deposit(AMOUNT, sender=a) + tx = vault.deposit(AMOUNT, sender=a) + + assert tx.events == [ + token.Transfer(a, vault, AMOUNT), + vault.Transfer(ZERO_ADDRESS, a, AMOUNT), + vault.Deposit(a, a, AMOUNT, AMOUNT), + ] assert vault.totalAssets() == AMOUNT assert vault.convertToAssets(10**18) == 10**18 # 1:1 price From daa9c31d71c16c9677eca8d036f25335bfefb0c0 Mon Sep 17 00:00:00 2001 From: fubuloubu <3859395+fubuloubu@users.noreply.github.com> Date: Tue, 25 Jul 2023 17:06:21 -0400 Subject: [PATCH 7/8] fix: ERC20 inherited contract already emits events --- contracts/SolidityVault.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/SolidityVault.sol b/contracts/SolidityVault.sol index 09d4a42..3704ea6 100644 --- a/contracts/SolidityVault.sol +++ b/contracts/SolidityVault.sol @@ -41,7 +41,7 @@ contract SolidityVault is IERC4626, ERC20 { _mint(receiver, shares); emit Deposit(msg.sender, receiver, assets, shares); - emit Transfer(address(0), receiver, shares); + // IMPORTANT: `_mint` does ERC20 `Transfer` log return shares; } @@ -69,7 +69,7 @@ contract SolidityVault is IERC4626, ERC20 { _mint(receiver, shares); emit Deposit(msg.sender, receiver, assets, shares); - emit Transfer(address(0), receiver, shares); + // IMPORTANT: `_mint` does ERC20 `Transfer` log return assets; } @@ -105,7 +105,7 @@ contract SolidityVault is IERC4626, ERC20 { ERC20(asset).transfer(receiver, assets); emit Withdraw(msg.sender, receiver, owner, assets, shares); - emit Transfer(owner, address(0), shares); + // IMPORTANT: `_burn` does ERC20 `Transfer` log return shares; } @@ -143,7 +143,7 @@ contract SolidityVault is IERC4626, ERC20 { ERC20(asset).transfer(receiver, assets); emit Withdraw(msg.sender, receiver, owner, assets, shares); - emit Transfer(owner, address(0), shares); + // IMPORTANT: `_burn` does ERC20 `Transfer` log return assets; } From 67403d2936634cd14fb35dafc187365a23040022 Mon Sep 17 00:00:00 2001 From: fubuloubu <3859395+fubuloubu@users.noreply.github.com> Date: Tue, 25 Jul 2023 17:06:42 -0400 Subject: [PATCH 8/8] fix: emit events in same order as solidity --- contracts/VyperVault.vy | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/VyperVault.vy b/contracts/VyperVault.vy index 4e31397..eb9cbf6 100644 --- a/contracts/VyperVault.vy +++ b/contracts/VyperVault.vy @@ -152,8 +152,8 @@ def deposit(assets: uint256, receiver: address=msg.sender) -> uint256: self.totalSupply += shares self.balanceOf[receiver] += shares - log Deposit(msg.sender, receiver, assets, shares) log Transfer(empty(address), receiver, shares) + log Deposit(msg.sender, receiver, assets, shares) return shares @@ -186,8 +186,8 @@ def mint(shares: uint256, receiver: address=msg.sender) -> uint256: self.totalSupply += shares self.balanceOf[receiver] += shares - log Deposit(msg.sender, receiver, assets, shares) log Transfer(empty(address), receiver, shares) + log Deposit(msg.sender, receiver, assets, shares) return assets @@ -224,8 +224,8 @@ def withdraw(assets: uint256, receiver: address=msg.sender, owner: address=msg.s self.balanceOf[owner] -= shares self.asset.transfer(receiver, assets) - log Withdraw(msg.sender, receiver, owner, assets, shares) log Transfer(owner, empty(address), shares) + log Withdraw(msg.sender, receiver, owner, assets, shares) return shares @@ -251,8 +251,8 @@ def redeem(shares: uint256, receiver: address=msg.sender, owner: address=msg.sen self.balanceOf[owner] -= shares self.asset.transfer(receiver, assets) - log Withdraw(msg.sender, receiver, owner, assets, shares) log Transfer(owner, empty(address), shares) + log Withdraw(msg.sender, receiver, owner, assets, shares) return assets