From 763902c68d2ec7b2627ac6fd5c5e7df7cd2cbe91 Mon Sep 17 00:00:00 2001 From: Cheng JIANG Date: Wed, 1 Nov 2023 19:46:54 +0800 Subject: [PATCH] Feat/improve position mover (#422) * feat: add to support for moving bendao position Signed-off-by: GopherJ * fix: tests Signed-off-by: GopherJ * fix: the import path of ScaledBalanceTokenBaseERC20 --------- Signed-off-by: GopherJ Co-authored-by: jfzhou5 <1241330802@qq.com> --- contracts/interfaces/IPoolPositionMover.sol | 5 ++- .../libraries/logic/PositionMoverLogic.sol | 23 ++++++++----- contracts/protocol/pool/PoolPositionMover.sol | 6 ++-- .../protocol/tokenization/PTokenSApe.sol | 2 +- .../tokenization/RebasingDebtToken.sol | 2 +- .../protocol/tokenization/RebasingPToken.sol | 2 +- test/_pool_position_mover.spec.ts | 32 ++++++++++++------- 7 files changed, 47 insertions(+), 25 deletions(-) diff --git a/contracts/interfaces/IPoolPositionMover.sol b/contracts/interfaces/IPoolPositionMover.sol index 768fb77b0..e5171d88e 100644 --- a/contracts/interfaces/IPoolPositionMover.sol +++ b/contracts/interfaces/IPoolPositionMover.sol @@ -10,7 +10,10 @@ import {ApeCoinStaking} from "../dependencies/yoga-labs/ApeCoinStaking.sol"; * @notice Defines the basic interface for an ParaSpace Pool. **/ interface IPoolPositionMover { - function movePositionFromBendDAO(uint256[] calldata loanIds) external; + function movePositionFromBendDAO( + uint256[] calldata loanIds, + address to + ) external; //# Migration step // diff --git a/contracts/protocol/libraries/logic/PositionMoverLogic.sol b/contracts/protocol/libraries/logic/PositionMoverLogic.sol index d73f39491..c3d33017c 100644 --- a/contracts/protocol/libraries/logic/PositionMoverLogic.sol +++ b/contracts/protocol/libraries/logic/PositionMoverLogic.sol @@ -76,7 +76,8 @@ library PositionMoverLogic { IPoolAddressesProvider poolAddressProvider, ILendPoolLoan lendPoolLoan, ILendPool lendPool, - uint256[] calldata loandIds + uint256[] calldata loandIds, + address to ) external { BendDAOPositionMoverVars memory tmpVar; @@ -97,7 +98,7 @@ library PositionMoverLogic { loandIds[index] ); - supplyNFTandBorrowWETH(ps, poolAddressProvider, tmpVar); + supplyNFTandBorrowWETH(ps, poolAddressProvider, tmpVar, to); emit PositionMovedFromBendDAO( tmpVar.nftAsset, @@ -143,8 +144,14 @@ library PositionMoverLogic { function supplyNFTandBorrowWETH( DataTypes.PoolStorage storage ps, IPoolAddressesProvider poolAddressProvider, - BendDAOPositionMoverVars memory tmpVar + BendDAOPositionMoverVars memory tmpVar, + address to ) internal { + require( + to == msg.sender || IAccount(to).owner() == msg.sender, + Errors.NOT_THE_OWNER + ); + DataTypes.ERC721SupplyParams[] memory tokenData = new DataTypes.ERC721SupplyParams[](1); tokenData[0] = DataTypes.ERC721SupplyParams({ @@ -154,11 +161,11 @@ library PositionMoverLogic { SupplyLogic.executeSupplyERC721( ps._reserves, - ps._usersConfig[msg.sender], + ps._usersConfig[to], DataTypes.ExecuteSupplyERC721Params({ asset: tmpVar.nftAsset, tokenData: tokenData, - onBehalfOf: msg.sender, + onBehalfOf: to, payer: msg.sender, referralCode: 0x0 }) @@ -167,11 +174,11 @@ library PositionMoverLogic { BorrowLogic.executeBorrow( ps._reserves, ps._reservesList, - ps._usersConfig[msg.sender], + ps._usersConfig[to], DataTypes.ExecuteBorrowParams({ asset: tmpVar.weth, - user: msg.sender, - onBehalfOf: msg.sender, + user: to, + onBehalfOf: to, amount: tmpVar.borrowAmount, referralCode: 0x0, releaseUnderlying: false, diff --git a/contracts/protocol/pool/PoolPositionMover.sol b/contracts/protocol/pool/PoolPositionMover.sol index 6f81ee4bd..4cbfbe0f4 100644 --- a/contracts/protocol/pool/PoolPositionMover.sol +++ b/contracts/protocol/pool/PoolPositionMover.sol @@ -74,7 +74,8 @@ contract PoolPositionMover is } function movePositionFromBendDAO( - uint256[] calldata loanIds + uint256[] calldata loanIds, + address to ) external nonReentrant { DataTypes.PoolStorage storage ps = poolStorage(); @@ -83,7 +84,8 @@ contract PoolPositionMover is ADDRESSES_PROVIDER, BENDDAO_LEND_POOL_LOAN, BENDDAO_LEND_POOL, - loanIds + loanIds, + to ); } diff --git a/contracts/protocol/tokenization/PTokenSApe.sol b/contracts/protocol/tokenization/PTokenSApe.sol index 54eacf18e..525f3fcb1 100644 --- a/contracts/protocol/tokenization/PTokenSApe.sol +++ b/contracts/protocol/tokenization/PTokenSApe.sol @@ -13,7 +13,7 @@ import {IERC20} from "../../dependencies/openzeppelin/contracts/IERC20.sol"; import {IScaledBalanceToken} from "../../interfaces/IScaledBalanceToken.sol"; import {IncentivizedERC20} from "./base/IncentivizedERC20.sol"; import {DataTypes} from "../libraries/types/DataTypes.sol"; -import {ScaledBalanceTokenBaseERC20} from "contracts/protocol/tokenization/base/ScaledBalanceTokenBaseERC20.sol"; +import {ScaledBalanceTokenBaseERC20} from "../../protocol/tokenization/base/ScaledBalanceTokenBaseERC20.sol"; /** * @title sApe PToken diff --git a/contracts/protocol/tokenization/RebasingDebtToken.sol b/contracts/protocol/tokenization/RebasingDebtToken.sol index da38850ff..ae1adbe88 100644 --- a/contracts/protocol/tokenization/RebasingDebtToken.sol +++ b/contracts/protocol/tokenization/RebasingDebtToken.sol @@ -7,7 +7,7 @@ import {WadRayMath} from "../libraries/math/WadRayMath.sol"; import {Errors} from "../libraries/helpers/Errors.sol"; import {SafeCast} from "../../dependencies/openzeppelin/contracts/SafeCast.sol"; import {IScaledBalanceToken} from "../../interfaces/IScaledBalanceToken.sol"; -import {ScaledBalanceTokenBaseERC20} from "contracts/protocol/tokenization/base/ScaledBalanceTokenBaseERC20.sol"; +import {ScaledBalanceTokenBaseERC20} from "../../protocol/tokenization/base/ScaledBalanceTokenBaseERC20.sol"; /** * @title Rebasing Debt Token diff --git a/contracts/protocol/tokenization/RebasingPToken.sol b/contracts/protocol/tokenization/RebasingPToken.sol index aeb820321..02ad0b4ec 100644 --- a/contracts/protocol/tokenization/RebasingPToken.sol +++ b/contracts/protocol/tokenization/RebasingPToken.sol @@ -10,7 +10,7 @@ import {Errors} from "../libraries/helpers/Errors.sol"; import {IERC20} from "../../dependencies/openzeppelin/contracts/IERC20.sol"; import {GPv2SafeERC20} from "../../dependencies/gnosis/contracts/GPv2SafeERC20.sol"; import {IScaledBalanceToken} from "../../interfaces/IScaledBalanceToken.sol"; -import {ScaledBalanceTokenBaseERC20} from "contracts/protocol/tokenization/base/ScaledBalanceTokenBaseERC20.sol"; +import {ScaledBalanceTokenBaseERC20} from "../../protocol/tokenization/base/ScaledBalanceTokenBaseERC20.sol"; /** * @title Rebasing PToken diff --git a/test/_pool_position_mover.spec.ts b/test/_pool_position_mover.spec.ts index bcb621459..43f1f1e1e 100644 --- a/test/_pool_position_mover.spec.ts +++ b/test/_pool_position_mover.spec.ts @@ -67,8 +67,9 @@ describe("Pool: rescue tokens", () => { 2 ); - await expect(pool.connect(user1.signer).movePositionFromBendDAO([1])).to.be - .reverted; + await expect( + pool.connect(user1.signer).movePositionFromBendDAO([1], user1.address) + ).to.be.reverted; }); it("moving position should succeed for an active loan", async () => { @@ -81,7 +82,11 @@ describe("Pool: rescue tokens", () => { } = testEnv; await supplyAndValidate(weth, "20000000000", user1, true); - await expect(await pool.connect(user1.signer).movePositionFromBendDAO([1])); + await expect( + await pool + .connect(user1.signer) + .movePositionFromBendDAO([1], user1.address) + ); await expect(await variableDebtWeth.balanceOf(user1.address)).to.be.eq( "200000" @@ -96,7 +101,7 @@ describe("Pool: rescue tokens", () => { } = testEnv; await expect( - pool.connect(user1.signer).movePositionFromBendDAO([1]) + pool.connect(user1.signer).movePositionFromBendDAO([1], user1.address) ).to.be.revertedWith("Loan not active"); }); @@ -119,8 +124,9 @@ describe("Pool: rescue tokens", () => { const agg = await getAggregator(undefined, await bayc.symbol()); await agg.updateLatestAnswer("100000"); - await expect(pool.connect(user2.signer).movePositionFromBendDAO([2])).to.be - .reverted; + await expect( + pool.connect(user2.signer).movePositionFromBendDAO([2], user2.address) + ).to.be.reverted; await changePriceAndValidate(bayc, "50"); }); @@ -141,8 +147,9 @@ describe("Pool: rescue tokens", () => { 2 ); - await expect(pool.connect(user2.signer).movePositionFromBendDAO([3])).to.be - .reverted; + await expect( + pool.connect(user2.signer).movePositionFromBendDAO([3], user2.address) + ).to.be.reverted; }); it("moving position should fail if the asset is not supported", async () => { @@ -174,8 +181,9 @@ describe("Pool: rescue tokens", () => { 2 ); - await expect(pool.connect(user1.signer).movePositionFromBendDAO([4])).to.be - .reverted; + await expect( + pool.connect(user1.signer).movePositionFromBendDAO([4], user1.address) + ).to.be.reverted; }); it("moving multiple positions should succeed for active loans", async () => { @@ -196,7 +204,9 @@ describe("Pool: rescue tokens", () => { ); await expect( - await pool.connect(user1.signer).movePositionFromBendDAO([3, 4]) + await pool + .connect(user1.signer) + .movePositionFromBendDAO([3, 4], user1.address) ); await expect(await variableDebtWeth.balanceOf(user1.address)).to.be.eq(