diff --git a/contracts/avalanche/connectors/approve-tokens-multisig-staging/events.sol b/contracts/avalanche/connectors/approve-tokens-multisig-staging/events.sol new file mode 100644 index 00000000..3daaaa03 --- /dev/null +++ b/contracts/avalanche/connectors/approve-tokens-multisig-staging/events.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract Events { + event LogApproveTokensMultisig(address[] tokenAddresses, uint256[] amounts, uint32 index); +} \ No newline at end of file diff --git a/contracts/avalanche/connectors/approve-tokens-multisig-staging/interface.sol b/contracts/avalanche/connectors/approve-tokens-multisig-staging/interface.sol new file mode 100644 index 00000000..3ae3daf3 --- /dev/null +++ b/contracts/avalanche/connectors/approve-tokens-multisig-staging/interface.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IAvoFactoryMultisig { + function computeAvocado(address owner_, uint32 index_) external view returns (address computedAddress_); +} \ No newline at end of file diff --git a/contracts/avalanche/connectors/approve-tokens-multisig-staging/main.sol b/contracts/avalanche/connectors/approve-tokens-multisig-staging/main.sol new file mode 100644 index 00000000..7dbec2e0 --- /dev/null +++ b/contracts/avalanche/connectors/approve-tokens-multisig-staging/main.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; +import "./events.sol"; +import "./interface.sol"; + +contract ApproveTokensResolver is Events { + using SafeERC20 for IERC20; + + IAvoFactoryMultisig public constant AVO_FACTORY = IAvoFactoryMultisig(0xe981E50c7c47F0Df8826B5ce3F533f5E4440e687); + + function approveTokens( + address[] calldata tokens, + uint256[] calldata amounts, + uint32 index + ) public returns (string memory _eventName, bytes memory _eventParam) { + require(tokens.length == amounts.length, "array-length-mismatch"); + + address avocadoAddress = AVO_FACTORY.computeAvocado(msg.sender, index); + + for (uint256 i = 0; i < tokens.length; i++) { + uint256 allowanceAmount = + amounts[i] == type(uint256).max + ? IERC20(tokens[i]).balanceOf(address(this)) + : amounts[i]; + IERC20(tokens[i]).safeApprove(avocadoAddress, allowanceAmount); + } + + _eventName = "LogApproveTokensMultisig(address[],uint256[],uint32)"; + _eventParam = abi.encode(tokens, amounts, index); + } +} + +contract ConnectV2ApproveTokensAvalanche is ApproveTokensResolver { + string constant public name = "ApproveTokens-v1"; +} \ No newline at end of file diff --git a/contracts/avalanche/connectors/approve-tokens-multisig/events.sol b/contracts/avalanche/connectors/approve-tokens-multisig/events.sol new file mode 100644 index 00000000..3daaaa03 --- /dev/null +++ b/contracts/avalanche/connectors/approve-tokens-multisig/events.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract Events { + event LogApproveTokensMultisig(address[] tokenAddresses, uint256[] amounts, uint32 index); +} \ No newline at end of file diff --git a/contracts/avalanche/connectors/approve-tokens-multisig/interface.sol b/contracts/avalanche/connectors/approve-tokens-multisig/interface.sol new file mode 100644 index 00000000..3ae3daf3 --- /dev/null +++ b/contracts/avalanche/connectors/approve-tokens-multisig/interface.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IAvoFactoryMultisig { + function computeAvocado(address owner_, uint32 index_) external view returns (address computedAddress_); +} \ No newline at end of file diff --git a/contracts/avalanche/connectors/approve-tokens-multisig/main.sol b/contracts/avalanche/connectors/approve-tokens-multisig/main.sol new file mode 100644 index 00000000..7dbec2e0 --- /dev/null +++ b/contracts/avalanche/connectors/approve-tokens-multisig/main.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; +import "./events.sol"; +import "./interface.sol"; + +contract ApproveTokensResolver is Events { + using SafeERC20 for IERC20; + + IAvoFactoryMultisig public constant AVO_FACTORY = IAvoFactoryMultisig(0xe981E50c7c47F0Df8826B5ce3F533f5E4440e687); + + function approveTokens( + address[] calldata tokens, + uint256[] calldata amounts, + uint32 index + ) public returns (string memory _eventName, bytes memory _eventParam) { + require(tokens.length == amounts.length, "array-length-mismatch"); + + address avocadoAddress = AVO_FACTORY.computeAvocado(msg.sender, index); + + for (uint256 i = 0; i < tokens.length; i++) { + uint256 allowanceAmount = + amounts[i] == type(uint256).max + ? IERC20(tokens[i]).balanceOf(address(this)) + : amounts[i]; + IERC20(tokens[i]).safeApprove(avocadoAddress, allowanceAmount); + } + + _eventName = "LogApproveTokensMultisig(address[],uint256[],uint32)"; + _eventParam = abi.encode(tokens, amounts, index); + } +} + +contract ConnectV2ApproveTokensAvalanche is ApproveTokensResolver { + string constant public name = "ApproveTokens-v1"; +} \ No newline at end of file