From 559fa652573731a4462028bc0cbbaaf09de9e31b Mon Sep 17 00:00:00 2001 From: Thor Seldon <94899282+thorseldon@users.noreply.github.com> Date: Sat, 16 Mar 2024 11:03:12 +0800 Subject: [PATCH] fix: Revert error for usdt approve (#33) --- .openzeppelin/mainnet.json | 276 ++++++++++++++++++++++++++--- contracts/misc/LendingMigrator.sol | 11 +- test/foundry/MigratorUSDT.t.sol | 54 ++++++ 3 files changed, 317 insertions(+), 24 deletions(-) create mode 100644 test/foundry/MigratorUSDT.t.sol diff --git a/.openzeppelin/mainnet.json b/.openzeppelin/mainnet.json index 60df79c..f432239 100644 --- a/.openzeppelin/mainnet.json +++ b/.openzeppelin/mainnet.json @@ -3626,7 +3626,7 @@ "label": "aaveAddressesProvider", "offset": 0, "slot": "201", - "type": "t_contract(IAaveLendPoolAddressesProvider)3646", + "type": "t_contract(IAaveLendPoolAddressesProvider)24463", "contract": "LendingMigrator", "src": "contracts/misc/LendingMigrator.sol:31" }, @@ -3634,7 +3634,7 @@ "label": "aaveLendPool", "offset": 0, "slot": "202", - "type": "t_contract(IAaveLendPool)3637", + "type": "t_contract(IAaveLendPool)24454", "contract": "LendingMigrator", "src": "contracts/misc/LendingMigrator.sol:32" }, @@ -3642,7 +3642,7 @@ "label": "bendAddressesProvider", "offset": 0, "slot": "203", - "type": "t_contract(ILendPoolAddressesProvider)3740", + "type": "t_contract(ILendPoolAddressesProvider)24571", "contract": "LendingMigrator", "src": "contracts/misc/LendingMigrator.sol:33" }, @@ -3650,7 +3650,7 @@ "label": "bendLendPool", "offset": 0, "slot": "204", - "type": "t_contract(ILendPool)3726", + "type": "t_contract(ILendPool)24557", "contract": "LendingMigrator", "src": "contracts/misc/LendingMigrator.sol:34" }, @@ -3658,7 +3658,7 @@ "label": "bendLendLoan", "offset": 0, "slot": "205", - "type": "t_contract(ILendPoolLoan)3759", + "type": "t_contract(ILendPoolLoan)24590", "contract": "LendingMigrator", "src": "contracts/misc/LendingMigrator.sol:35" }, @@ -3666,7 +3666,7 @@ "label": "nftPool", "offset": 0, "slot": "206", - "type": "t_contract(INftPool)1907", + "type": "t_contract(INftPool)20454", "contract": "LendingMigrator", "src": "contracts/misc/LendingMigrator.sol:37" }, @@ -3674,7 +3674,7 @@ "label": "stBayc", "offset": 0, "slot": "207", - "type": "t_contract(IStakedNft)2297", + "type": "t_contract(IStakedNft)21327", "contract": "LendingMigrator", "src": "contracts/misc/LendingMigrator.sol:38" }, @@ -3682,7 +3682,7 @@ "label": "stMayc", "offset": 0, "slot": "208", - "type": "t_contract(IStakedNft)2297", + "type": "t_contract(IStakedNft)21327", "contract": "LendingMigrator", "src": "contracts/misc/LendingMigrator.sol:39" }, @@ -3690,7 +3690,7 @@ "label": "stBakc", "offset": 0, "slot": "209", - "type": "t_contract(IStakedNft)2297", + "type": "t_contract(IStakedNft)21327", "contract": "LendingMigrator", "src": "contracts/misc/LendingMigrator.sol:40" }, @@ -3698,7 +3698,7 @@ "label": "bayc", "offset": 0, "slot": "210", - "type": "t_contract(IERC721Upgradeable)1038", + "type": "t_contract(IERC721Upgradeable)3501", "contract": "LendingMigrator", "src": "contracts/misc/LendingMigrator.sol:42" }, @@ -3706,7 +3706,7 @@ "label": "mayc", "offset": 0, "slot": "211", - "type": "t_contract(IERC721Upgradeable)1038", + "type": "t_contract(IERC721Upgradeable)3501", "contract": "LendingMigrator", "src": "contracts/misc/LendingMigrator.sol:43" }, @@ -3714,7 +3714,7 @@ "label": "bakc", "offset": 0, "slot": "212", - "type": "t_contract(IERC721Upgradeable)1038", + "type": "t_contract(IERC721Upgradeable)3501", "contract": "LendingMigrator", "src": "contracts/misc/LendingMigrator.sol:44" } @@ -3736,35 +3736,35 @@ "label": "bool", "numberOfBytes": "1" }, - "t_contract(IAaveLendPool)3637": { + "t_contract(IAaveLendPool)24454": { "label": "contract IAaveLendPool", "numberOfBytes": "20" }, - "t_contract(IAaveLendPoolAddressesProvider)3646": { + "t_contract(IAaveLendPoolAddressesProvider)24463": { "label": "contract IAaveLendPoolAddressesProvider", "numberOfBytes": "20" }, - "t_contract(IERC721Upgradeable)1038": { + "t_contract(IERC721Upgradeable)3501": { "label": "contract IERC721Upgradeable", "numberOfBytes": "20" }, - "t_contract(ILendPool)3726": { + "t_contract(ILendPool)24557": { "label": "contract ILendPool", "numberOfBytes": "20" }, - "t_contract(ILendPoolAddressesProvider)3740": { + "t_contract(ILendPoolAddressesProvider)24571": { "label": "contract ILendPoolAddressesProvider", "numberOfBytes": "20" }, - "t_contract(ILendPoolLoan)3759": { + "t_contract(ILendPoolLoan)24590": { "label": "contract ILendPoolLoan", "numberOfBytes": "20" }, - "t_contract(INftPool)1907": { + "t_contract(INftPool)20454": { "label": "contract INftPool", "numberOfBytes": "20" }, - "t_contract(IStakedNft)2297": { + "t_contract(IStakedNft)21327": { "label": "contract IStakedNft", "numberOfBytes": "20" }, @@ -6586,6 +6586,242 @@ } } } + }, + "9704f7adf3770660a0e6b3bc5c5daed667f94919b9452ab41f050d09b7b06106": { + "address": "0x7A4CdEa27964491F32A09F835116614d2C8dbF69", + "txHash": "0xdd53ff61e0a4ecb67a020f6e8dd3b8edd271a4cd05d75b3df82f58691a2a5740", + "layout": { + "solcVersion": "0.8.18", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" + }, + { + "label": "_status", + "offset": 0, + "slot": "1", + "type": "t_uint256", + "contract": "ReentrancyGuardUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" + }, + { + "label": "__gap", + "offset": 0, + "slot": "2", + "type": "t_array(t_uint256)49_storage", + "contract": "ReentrancyGuardUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:80" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_owner", + "offset": 0, + "slot": "101", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "102", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "_paused", + "offset": 0, + "slot": "151", + "type": "t_bool", + "contract": "PausableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" + }, + { + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage", + "contract": "PausableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" + }, + { + "label": "aaveAddressesProvider", + "offset": 0, + "slot": "201", + "type": "t_contract(IAaveLendPoolAddressesProvider)3702", + "contract": "LendingMigrator", + "src": "contracts/misc/LendingMigrator.sol:34" + }, + { + "label": "aaveLendPool", + "offset": 0, + "slot": "202", + "type": "t_contract(IAaveLendPool)3693", + "contract": "LendingMigrator", + "src": "contracts/misc/LendingMigrator.sol:35" + }, + { + "label": "bendAddressesProvider", + "offset": 0, + "slot": "203", + "type": "t_contract(ILendPoolAddressesProvider)3796", + "contract": "LendingMigrator", + "src": "contracts/misc/LendingMigrator.sol:36" + }, + { + "label": "bendLendPool", + "offset": 0, + "slot": "204", + "type": "t_contract(ILendPool)3782", + "contract": "LendingMigrator", + "src": "contracts/misc/LendingMigrator.sol:37" + }, + { + "label": "bendLendLoan", + "offset": 0, + "slot": "205", + "type": "t_contract(ILendPoolLoan)3815", + "contract": "LendingMigrator", + "src": "contracts/misc/LendingMigrator.sol:38" + }, + { + "label": "nftPool", + "offset": 0, + "slot": "206", + "type": "t_contract(INftPool)1907", + "contract": "LendingMigrator", + "src": "contracts/misc/LendingMigrator.sol:40" + }, + { + "label": "stBayc", + "offset": 0, + "slot": "207", + "type": "t_contract(IStakedNft)2347", + "contract": "LendingMigrator", + "src": "contracts/misc/LendingMigrator.sol:41" + }, + { + "label": "stMayc", + "offset": 0, + "slot": "208", + "type": "t_contract(IStakedNft)2347", + "contract": "LendingMigrator", + "src": "contracts/misc/LendingMigrator.sol:42" + }, + { + "label": "stBakc", + "offset": 0, + "slot": "209", + "type": "t_contract(IStakedNft)2347", + "contract": "LendingMigrator", + "src": "contracts/misc/LendingMigrator.sol:43" + }, + { + "label": "bayc", + "offset": 0, + "slot": "210", + "type": "t_contract(IERC721Upgradeable)1038", + "contract": "LendingMigrator", + "src": "contracts/misc/LendingMigrator.sol:45" + }, + { + "label": "mayc", + "offset": 0, + "slot": "211", + "type": "t_contract(IERC721Upgradeable)1038", + "contract": "LendingMigrator", + "src": "contracts/misc/LendingMigrator.sol:46" + }, + { + "label": "bakc", + "offset": 0, + "slot": "212", + "type": "t_contract(IERC721Upgradeable)1038", + "contract": "LendingMigrator", + "src": "contracts/misc/LendingMigrator.sol:47" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_contract(IAaveLendPool)3693": { + "label": "contract IAaveLendPool", + "numberOfBytes": "20" + }, + "t_contract(IAaveLendPoolAddressesProvider)3702": { + "label": "contract IAaveLendPoolAddressesProvider", + "numberOfBytes": "20" + }, + "t_contract(IERC721Upgradeable)1038": { + "label": "contract IERC721Upgradeable", + "numberOfBytes": "20" + }, + "t_contract(ILendPool)3782": { + "label": "contract ILendPool", + "numberOfBytes": "20" + }, + "t_contract(ILendPoolAddressesProvider)3796": { + "label": "contract ILendPoolAddressesProvider", + "numberOfBytes": "20" + }, + "t_contract(ILendPoolLoan)3815": { + "label": "contract ILendPoolLoan", + "numberOfBytes": "20" + }, + "t_contract(INftPool)1907": { + "label": "contract INftPool", + "numberOfBytes": "20" + }, + "t_contract(IStakedNft)2347": { + "label": "contract IStakedNft", + "numberOfBytes": "20" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + } + } } } } diff --git a/contracts/misc/LendingMigrator.sol b/contracts/misc/LendingMigrator.sol index aa4e22d..67386ef 100644 --- a/contracts/misc/LendingMigrator.sol +++ b/contracts/misc/LendingMigrator.sol @@ -4,8 +4,9 @@ pragma solidity 0.8.18; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; -import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; +import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import {IERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol"; +import {SafeERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; import {IAaveLendPoolAddressesProvider} from "./interfaces/IAaveLendPoolAddressesProvider.sol"; import {IAaveLendPool} from "./interfaces/IAaveLendPool.sol"; @@ -23,6 +24,8 @@ contract LendingMigrator is OwnableUpgradeable, PausableUpgradeable { + using SafeERC20Upgradeable for IERC20Upgradeable; + event NftMigrated(address indexed borrower, address indexed nftAsset, uint256 nftTokenId, uint256 debtAmount); uint256 public constant PERCENTAGE_FACTOR = 1e4; @@ -190,7 +193,7 @@ contract LendingMigrator is (address, address[], uint256[], uint256[]) ); - IERC20Upgradeable(assets[0]).approve(address(bendLendPool), type(uint256).max); + IERC20Upgradeable(assets[0]).safeApprove(address(bendLendPool), type(uint256).max); for (uint256 i = 0; i < execVars.nftTokenIds.length; i++) { RepayAndBorrowLocaVars memory vars; @@ -201,10 +204,10 @@ contract LendingMigrator is _repayAndBorrowPerNft(execVars, vars); } - IERC20Upgradeable(assets[0]).approve(address(bendLendPool), 0); + IERC20Upgradeable(assets[0]).safeApprove(address(bendLendPool), 0); execVars.repayToAave = amounts[0] + premiums[0]; - IERC20Upgradeable(assets[0]).approve(msg.sender, execVars.repayToAave); + IERC20Upgradeable(assets[0]).safeApprove(msg.sender, execVars.repayToAave); return true; } diff --git a/test/foundry/MigratorUSDT.t.sol b/test/foundry/MigratorUSDT.t.sol new file mode 100644 index 0000000..21537e0 --- /dev/null +++ b/test/foundry/MigratorUSDT.t.sol @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.18; + +import "forge-std/Test.sol"; + +import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; +import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; + +import "../../contracts/misc/LendingMigrator.sol"; + +contract TestMigratorUSDT is Test { + using SafeERC20 for IERC20; + + // the address of the contract on the mainnet fork + address constant multisigOwnerAddress = 0xe6b80f77a8B8FcD124aB748C720B7EAEA83dDb4C; + address constant timelockController7DAddress = 0x4e4C314E2391A58775be6a15d7A05419ba7D2B6e; + address constant proxyAdminAddress = 0xcfCF3A49552EC920497EE0DEbC965C31044D0118; + + address constant migratorAddress = 0x968c9090a217786f414025ceF11540f801f38ee1; + address constant userAddress = 0x8F45D77F7c0D8e4023eAb2A2e36C83667c6B0253; + address constant nftAddress = 0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D; + // contracts + ProxyAdmin public proxyAdmin; + LendingMigrator public migrator; + + // how to run this testcase + // url: https://eth-mainnet.g.alchemy.com/v2/xxx + // forge test --match-contract TestMigratorUSDT --fork-url https://RPC --fork-block-number 19425293 + + function setUp() public { + proxyAdmin = ProxyAdmin(proxyAdminAddress); + migrator = LendingMigrator(migratorAddress); + } + + function testMigrate() public { + // upgrade contract + LendingMigrator migratorImpl = new LendingMigrator(); + + vm.prank(timelockController7DAddress); + proxyAdmin.upgrade(ITransparentUpgradeableProxy(migratorAddress), address(migratorImpl)); + + // try migrate + address[] memory nftAssets = new address[](1); + nftAssets[0] = nftAddress; + uint256[] memory nftTokenIds = new uint256[](1); + nftTokenIds[0] = 6890; + + vm.prank(userAddress); + migrator.migrate(nftAssets, nftTokenIds); + } +}