diff --git a/.github/workflows/foundry.yaml b/.github/workflows/foundry.yaml index 607d7a75..ebc1ede3 100644 --- a/.github/workflows/foundry.yaml +++ b/.github/workflows/foundry.yaml @@ -19,43 +19,16 @@ jobs: - ubuntu-latest architecture: - "x64" - python-version: - - "3.10" - node_version: - - 16 steps: - name: Checkout uses: actions/checkout@v3 with: submodules: recursive - - - name: Setup Python - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - architecture: ${{ matrix.architecture }} - - - name: Install Ape - uses: ApeWorX/github-action@v2.0 - with: - python-version: '3.10' - - - name: install vyper - run: pip install git+https://github.com/vyperlang/vyper - - - name: Compile contracts - # Compile Ape contracts to get dependencies - run: ape compile --force --size - + - name: Install Vyper run: pip install vyper==0.3.7 - - name: Use Node.js ${{ matrix.node_version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node_version }} - - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 with: diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index d513b6ab..9f2c89d4 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -28,10 +28,10 @@ jobs: with: fetch-depth: 1 - - name: Set up python 3.8 + - name: Set up python 3.9 uses: actions/setup-python@v2 with: - python-version: 3.8 + python-version: 3.9 - name: Set pip cache directory path id: pip-cache-dir-path diff --git a/.gitmodules b/.gitmodules index 665e0dd7..9e1e5be8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,10 @@ [submodule "lib/erc4626-tests"] path = lib/erc4626-tests url = https://github.com/a16z/erc4626-tests +[submodule "lib/openzeppelin-contracts"] + path = lib/openzeppelin-contracts + url = https://github.com/OpenZeppelin/openzeppelin-contracts + release = v4.9.5 +[submodule "lib/tokenized-strategy"] + path = lib/tokenized-strategy + url = https://github.com/yearn/tokenized-strategy diff --git a/contracts/VaultV3.vy b/contracts/VaultV3.vy index 8b51b81e..d8f9e631 100644 --- a/contracts/VaultV3.vy +++ b/contracts/VaultV3.vy @@ -663,19 +663,25 @@ def _deposit(sender: address, recipient: address, assets: uint256) -> uint256: vault accounting. """ assert self.shutdown == False # dev: shutdown - assert assets <= self._max_deposit(recipient), "exceed deposit limit" + + amount: uint256 = assets + # Deposit all if sent with max uint + if amount == max_value(uint256): + amount = ERC20(self.asset).balanceOf(msg.sender) + + assert amount <= self._max_deposit(recipient), "exceed deposit limit" # Transfer the tokens to the vault first. - self._erc20_safe_transfer_from(self.asset, msg.sender, self, assets) + self._erc20_safe_transfer_from(self.asset, msg.sender, self, amount) # Record the change in total assets. - self.total_idle += assets + self.total_idle += amount - # Issue the corresponding shares for assets. - shares: uint256 = self._issue_shares_for_amount(assets, recipient) + # Issue the corresponding shares for amount. + shares: uint256 = self._issue_shares_for_amount(amount, recipient) assert shares > 0, "cannot mint zero" - log Deposit(sender, recipient, assets, shares) + log Deposit(sender, recipient, amount, shares) return shares @internal diff --git a/foundry.toml b/foundry.toml index 047eaac0..864746bc 100644 --- a/foundry.toml +++ b/foundry.toml @@ -8,8 +8,8 @@ libs = ['lib'] remappings = [ 'forge-std/=lib/forge-std/src/', 'erc4626-tests/=lib/erc4626-tests/', - "@tokenized-strategy=contracts/.cache/tokenized-strategy/v3.0.2", - '@openzeppelin/contracts=contracts/.cache/openzeppelin/v4.9.5/', + "@tokenized-strategy=lib/tokenized-strategy/src", + '@openzeppelin/=lib/openzeppelin-contracts/', ] fs_permissions = [{ access = "read", path = "./"}] diff --git a/foundry_tests/tests/ERC4626Std.t.sol b/foundry_tests/tests/ERC4626Std.t.sol index 7d7162ef..c3de553a 100644 --- a/foundry_tests/tests/ERC4626Std.t.sol +++ b/foundry_tests/tests/ERC4626Std.t.sol @@ -29,6 +29,24 @@ contract VaultERC4626StdTest is ERC4626Test, Setup { super.test_maxRedeem(init); } + //Avoid special case for deposits of uint256 max + function test_previewDeposit( + Init memory init, + uint assets + ) public override { + if (assets == type(uint256).max) assets -= 1; + super.test_previewDeposit(init, assets); + } + + function test_deposit( + Init memory init, + uint assets, + uint allowance + ) public override { + if (assets == type(uint256).max) assets -= 1; + super.test_deposit(init, assets, allowance); + } + function clamp( Init memory init, uint max diff --git a/lib/openzeppelin-contracts b/lib/openzeppelin-contracts new file mode 160000 index 00000000..bd325d56 --- /dev/null +++ b/lib/openzeppelin-contracts @@ -0,0 +1 @@ +Subproject commit bd325d56b4c62c9c5c1aff048c37c6bb18ac0290 diff --git a/lib/tokenized-strategy b/lib/tokenized-strategy new file mode 160000 index 00000000..0d90dee1 --- /dev/null +++ b/lib/tokenized-strategy @@ -0,0 +1 @@ +Subproject commit 0d90dee170d53a0e04af3ff41d2f7a4f3ac395bd diff --git a/tests/unit/vault/test_erc4626.py b/tests/unit/vault/test_erc4626.py index 4d4f6d0f..9504fedd 100644 --- a/tests/unit/vault/test_erc4626.py +++ b/tests/unit/vault/test_erc4626.py @@ -785,6 +785,29 @@ def test_max_redeem__with_withdraw_limit_module( assert vault.maxRedeem(bunny.address) == 0 +def test_deposit__with_max_uint( + asset, fish, fish_amount, gov, create_vault, deploy_limit_module, user_deposit +): + vault = create_vault(asset) + assets = fish_amount + + assert asset.balanceOf(fish) == fish_amount + + asset.approve(vault.address, assets, sender=fish) + + # Should go through now + tx = vault.deposit(MAX_INT, fish.address, sender=fish) + + event = list(tx.decode_logs(vault.Deposit))[0] + + assert event.assets == assets + assert event.shares == assets + assert event.owner == fish + assert event.sender == fish + assert vault.balanceOf(fish.address) == assets + assert asset.balanceOf(vault.address) == assets + + def test_deposit__with_deposit_limit_module( asset, fish, fish_amount, gov, create_vault, deploy_limit_module, user_deposit ):