diff --git a/contracts/arbitrum/connectors/approve-tokens/events.sol b/contracts/arbitrum/connectors/approve-tokens/events.sol new file mode 100644 index 00000000..704273be --- /dev/null +++ b/contracts/arbitrum/connectors/approve-tokens/events.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; + +contract Events { + event LogApproveTokens(address[] tokenAddresses, uint256[] amounts); +} \ No newline at end of file diff --git a/contracts/arbitrum/connectors/approve-tokens/interface.sol b/contracts/arbitrum/connectors/approve-tokens/interface.sol new file mode 100644 index 00000000..38abe986 --- /dev/null +++ b/contracts/arbitrum/connectors/approve-tokens/interface.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; + +interface IAvoFactory { + function computeAddress(address owner_) external view returns (address); +} \ No newline at end of file diff --git a/contracts/arbitrum/connectors/approve-tokens/main.sol b/contracts/arbitrum/connectors/approve-tokens/main.sol new file mode 100644 index 00000000..9545d04f --- /dev/null +++ b/contracts/arbitrum/connectors/approve-tokens/main.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.7.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; + + IAvoFactory public constant AVO_FACTORY = IAvoFactory(0x3AdAE9699029AB2953F607AE1f62372681D35978); + + function approveTokens( + address[] calldata tokens, + uint256[] calldata amounts + ) public returns (string memory _eventName, bytes memory _eventParam) { + require(tokens.length == amounts.length, "array-length-mismatch"); + + address avocadoAddress = AVO_FACTORY.computeAddress(msg.sender); + + 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 = "LogApproveTokens(address[],uint256[])"; + _eventParam = abi.encode(tokens, amounts); + } +} + +contract ConnectV2ApproveTokensArbitrum is ApproveTokensResolver { + string constant public name = "ApproveTokens-v1"; +} \ No newline at end of file diff --git a/contracts/avalanche/connectors/approve-tokens/events.sol b/contracts/avalanche/connectors/approve-tokens/events.sol new file mode 100644 index 00000000..704273be --- /dev/null +++ b/contracts/avalanche/connectors/approve-tokens/events.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; + +contract Events { + event LogApproveTokens(address[] tokenAddresses, uint256[] amounts); +} \ No newline at end of file diff --git a/contracts/avalanche/connectors/approve-tokens/interface.sol b/contracts/avalanche/connectors/approve-tokens/interface.sol new file mode 100644 index 00000000..38abe986 --- /dev/null +++ b/contracts/avalanche/connectors/approve-tokens/interface.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; + +interface IAvoFactory { + function computeAddress(address owner_) external view returns (address); +} \ No newline at end of file diff --git a/contracts/avalanche/connectors/approve-tokens/main.sol b/contracts/avalanche/connectors/approve-tokens/main.sol new file mode 100644 index 00000000..b7d2cd82 --- /dev/null +++ b/contracts/avalanche/connectors/approve-tokens/main.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.7.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; + + IAvoFactory public constant AVO_FACTORY = IAvoFactory(0x3AdAE9699029AB2953F607AE1f62372681D35978); + + function approveTokens( + address[] calldata tokens, + uint256[] calldata amounts + ) public returns (string memory _eventName, bytes memory _eventParam) { + require(tokens.length == amounts.length, "array-length-mismatch"); + + address avocadoAddress = AVO_FACTORY.computeAddress(msg.sender); + + 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 = "LogApproveTokens(address[],uint256[])"; + _eventParam = abi.encode(tokens, amounts); + } +} + +contract ConnectV2ApproveTokensAvalanche is ApproveTokensResolver { + string constant public name = "ApproveTokens-v1"; +} \ No newline at end of file diff --git a/contracts/mainnet/connectors/approve-tokens/events.sol b/contracts/mainnet/connectors/approve-tokens/events.sol new file mode 100644 index 00000000..704273be --- /dev/null +++ b/contracts/mainnet/connectors/approve-tokens/events.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; + +contract Events { + event LogApproveTokens(address[] tokenAddresses, uint256[] amounts); +} \ No newline at end of file diff --git a/contracts/mainnet/connectors/approve-tokens/interface.sol b/contracts/mainnet/connectors/approve-tokens/interface.sol new file mode 100644 index 00000000..38abe986 --- /dev/null +++ b/contracts/mainnet/connectors/approve-tokens/interface.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; + +interface IAvoFactory { + function computeAddress(address owner_) external view returns (address); +} \ No newline at end of file diff --git a/contracts/mainnet/connectors/approve-tokens/main.sol b/contracts/mainnet/connectors/approve-tokens/main.sol new file mode 100644 index 00000000..caea31af --- /dev/null +++ b/contracts/mainnet/connectors/approve-tokens/main.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.7.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; + + IAvoFactory public constant AVO_FACTORY = IAvoFactory(0x3AdAE9699029AB2953F607AE1f62372681D35978); + + function approveTokens( + address[] calldata tokens, + uint256[] calldata amounts + ) public returns (string memory _eventName, bytes memory _eventParam) { + require(tokens.length == amounts.length, "array-length-mismatch"); + + address avocadoAddress = AVO_FACTORY.computeAddress(msg.sender); + + 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 = "LogApproveTokens(address[],uint256[])"; + _eventParam = abi.encode(tokens, amounts); + } +} + +contract ConnectV2ApproveTokens is ApproveTokensResolver { + string constant public name = "ApproveTokens-v1"; +} \ No newline at end of file diff --git a/contracts/optimism/connectors/approve-tokens/events.sol b/contracts/optimism/connectors/approve-tokens/events.sol new file mode 100644 index 00000000..704273be --- /dev/null +++ b/contracts/optimism/connectors/approve-tokens/events.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; + +contract Events { + event LogApproveTokens(address[] tokenAddresses, uint256[] amounts); +} \ No newline at end of file diff --git a/contracts/optimism/connectors/approve-tokens/interface.sol b/contracts/optimism/connectors/approve-tokens/interface.sol new file mode 100644 index 00000000..38abe986 --- /dev/null +++ b/contracts/optimism/connectors/approve-tokens/interface.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; + +interface IAvoFactory { + function computeAddress(address owner_) external view returns (address); +} \ No newline at end of file diff --git a/contracts/optimism/connectors/approve-tokens/main.sol b/contracts/optimism/connectors/approve-tokens/main.sol new file mode 100644 index 00000000..b1a22daa --- /dev/null +++ b/contracts/optimism/connectors/approve-tokens/main.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.7.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; + + IAvoFactory public constant AVO_FACTORY = IAvoFactory(0x3AdAE9699029AB2953F607AE1f62372681D35978); + + function approveTokens( + address[] calldata tokens, + uint256[] calldata amounts + ) public returns (string memory _eventName, bytes memory _eventParam) { + require(tokens.length == amounts.length, "array-length-mismatch"); + + address avocadoAddress = AVO_FACTORY.computeAddress(msg.sender); + + 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 = "LogApproveTokens(address[],uint256[])"; + _eventParam = abi.encode(tokens, amounts); + } +} + +contract ConnectV2ApproveTokensOptimism is ApproveTokensResolver { + string constant public name = "ApproveTokens-v1"; +} \ No newline at end of file diff --git a/contracts/polygon/connectors/approve-tokens/events.sol b/contracts/polygon/connectors/approve-tokens/events.sol new file mode 100644 index 00000000..704273be --- /dev/null +++ b/contracts/polygon/connectors/approve-tokens/events.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; + +contract Events { + event LogApproveTokens(address[] tokenAddresses, uint256[] amounts); +} \ No newline at end of file diff --git a/contracts/polygon/connectors/approve-tokens/interface.sol b/contracts/polygon/connectors/approve-tokens/interface.sol new file mode 100644 index 00000000..38abe986 --- /dev/null +++ b/contracts/polygon/connectors/approve-tokens/interface.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; + +interface IAvoFactory { + function computeAddress(address owner_) external view returns (address); +} \ No newline at end of file diff --git a/contracts/polygon/connectors/approve-tokens/main.sol b/contracts/polygon/connectors/approve-tokens/main.sol new file mode 100644 index 00000000..33f1e421 --- /dev/null +++ b/contracts/polygon/connectors/approve-tokens/main.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.7.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; + + IAvoFactory public constant AVO_FACTORY = IAvoFactory(0x3AdAE9699029AB2953F607AE1f62372681D35978); + + function approveTokens( + address[] calldata tokens, + uint256[] calldata amounts + ) public returns (string memory _eventName, bytes memory _eventParam) { + require(tokens.length == amounts.length, "array-length-mismatch"); + + address avocadoAddress = AVO_FACTORY.computeAddress(msg.sender); + + 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 = "LogApproveTokens(address[],uint256[])"; + _eventParam = abi.encode(tokens, amounts); + } +} + +contract ConnectV2ApproveTokensPolygon is ApproveTokensResolver { + string constant public name = "ApproveTokens-v1"; +} \ No newline at end of file