diff --git a/contracts-periphery/.env.example b/contracts-periphery/.env.example index 01c571e41..45b965c3b 100644 --- a/contracts-periphery/.env.example +++ b/contracts-periphery/.env.example @@ -3,4 +3,5 @@ POLYGON_RPC_URL= OPTIMISM_RPC_URL= ARBITRUM_ONE_RPC_URL= GNOSIS_CHAIN_RPC_URL= -SEPOLIA_RPC_URL= \ No newline at end of file +SEPOLIA_RPC_URL= +PRIVATE_KEY=yourPrivateKeyHere \ No newline at end of file diff --git a/contracts-periphery/README.md b/contracts-periphery/README.md index b2caf5218..7be7789d5 100644 --- a/contracts-periphery/README.md +++ b/contracts-periphery/README.md @@ -31,3 +31,19 @@ This repo uses [Foundry](https://github.com/gakonst/foundry). 7. Execute the deploy by broadcasting the deploy transactions. - `forge script DeployBatchSend --private-key --broadcast` + +### How to use the ApproveTokens Script + +1. Inside `contracts-periphery` folder, run `cp .env.example .env` and fill out all fields. +2. In your terminal use command `source .env` to load the environment variables. +3. To make sure the script test passes, run + +- `forge test --mc ApproveBatchSendTokensTest --sender ` + +4. To dry run the script pass in the `--private-key` flag and the desired network in the `--rpc-url` flag. Contract and token addresses should be specific to the network specified in the `--rpc-url` flag. + +- `forge script ApproveBatchSendTokens --sig "run(address,address,address[])" "[,]" --rpc-url $MAINNET_RPC_URL --private-key $PRIVATE_KEY` + +4. Execute the script by adding the broadcasting flag. + +- `forge script ApproveBatchSendTokens --sig "run(address,address,address[])" "[,]" --rpc-url $MAINNET_RPC_URL --private-key $PRIVATE_KEY --broadcast` diff --git a/contracts-periphery/script/ApproveBatchSendTokens.s.sol b/contracts-periphery/script/ApproveBatchSendTokens.s.sol new file mode 100644 index 000000000..129145be5 --- /dev/null +++ b/contracts-periphery/script/ApproveBatchSendTokens.s.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.16; + +import {Script} from "forge-std/Script.sol"; +import {IERC20} from "openzeppelin-contracts/token/ERC20/IERC20.sol"; +import {UmbraBatchSend} from "src/UmbraBatchSend.sol"; + +contract ApproveBatchSendTokens is Script { + function run( + address _umbraContractAddress, + address _batchSendContractAddress, + address[] calldata _tokenAddressesToApprove + ) public { + vm.startBroadcast(); + for (uint256 i = 0; i < _tokenAddressesToApprove.length; i++) { + uint256 _currentAllowance = IERC20(_tokenAddressesToApprove[i]).allowance( + _batchSendContractAddress, _umbraContractAddress + ); + if (_currentAllowance == 0) { + UmbraBatchSend(_batchSendContractAddress).approveToken(IERC20(_tokenAddressesToApprove[i])); + } + } + vm.stopBroadcast(); + } +} diff --git a/contracts-periphery/test/ApproveBatchSendTokens.t.sol b/contracts-periphery/test/ApproveBatchSendTokens.t.sol new file mode 100644 index 000000000..9e774f4df --- /dev/null +++ b/contracts-periphery/test/ApproveBatchSendTokens.t.sol @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.16; + +import {Test, console2} from "forge-std/Test.sol"; +import {ApproveBatchSendTokens} from "script/ApproveBatchSendTokens.s.sol"; +import {IERC20} from "openzeppelin-contracts/token/ERC20/IERC20.sol"; + +contract ApproveBatchSendTokensTest is Test { + ApproveBatchSendTokens approveTokensScript; + address umbraContractAddressOnMainnet = 0xFb2dc580Eed955B528407b4d36FfaFe3da685401; + address batchSendContractAddressOnMainnet = 0xDbD0f5EBAdA6632Dde7d47713ea200a7C2ff91EB; + address constant DAI_ADDRESS = 0x6B175474E89094C44Da98b954EedeAC495271d0F; + address constant LUSD_ADDRESS = 0x5f98805A4E8be255a32880FDeC7F6728C6568bA0; + address constant RAI_ADDRESS = 0x03ab458634910AaD20eF5f1C8ee96F1D6ac54919; + address constant USDC_ADDRESS = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; + address constant USDT_ADDRESS = 0xdAC17F958D2ee523a2206206994597C13D831ec7; + address constant WBTC_ADDRESS = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599; + address[] tokensToApprove = + [DAI_ADDRESS, LUSD_ADDRESS, RAI_ADDRESS, USDC_ADDRESS, USDT_ADDRESS, WBTC_ADDRESS]; + + function setUp() public { + vm.createSelectFork(vm.rpcUrl("mainnet")); + approveTokensScript = new ApproveBatchSendTokens(); + } + + function test_ApproveSingleToken() public { + address[] memory tokenAddressesToApprove = new address[](1); + tokenAddressesToApprove[0] = DAI_ADDRESS; + approveTokensScript.run( + umbraContractAddressOnMainnet, batchSendContractAddressOnMainnet, tokenAddressesToApprove + ); + + assertEq( + IERC20(DAI_ADDRESS).allowance( + batchSendContractAddressOnMainnet, umbraContractAddressOnMainnet + ), + type(uint256).max + ); + } + + function test_ApproveMultipleTokens() public { + approveTokensScript.run( + umbraContractAddressOnMainnet, batchSendContractAddressOnMainnet, tokensToApprove + ); + + for (uint256 _i; _i < tokensToApprove.length; _i++) { + assertEq( + IERC20(tokensToApprove[_i]).allowance( + batchSendContractAddressOnMainnet, umbraContractAddressOnMainnet + ), + type(uint256).max + ); + } + } +}