Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ape Staking V2 #403

Merged
merged 106 commits into from
Dec 11, 2023
Merged
Changes from 1 commit
Commits
Show all changes
106 commits
Select commit Hold shift + click to select a range
2aca3a0
feat: improve auto compound
GopherJ May 4, 2023
09205a5
chore: fallback to onchain slippage
GopherJ May 4, 2023
4935ac5
feat: change p2p fee logic
GopherJ May 4, 2023
35f9863
feat: seperate compoundBot & matchingOperator
GopherJ May 6, 2023
807b966
feat: put slippage offchain
GopherJ May 6, 2023
7b42745
fix: lint
GopherJ May 6, 2023
6e1c2dd
fix: typo
GopherJ May 6, 2023
c686c37
chore: gas optimize
GopherJ May 6, 2023
cc60418
fix: gas optimize
GopherJ May 6, 2023
4270ed3
fix: check swapAmount before transfer
GopherJ May 6, 2023
a174e33
fix: part of tests
GopherJ May 8, 2023
ec2dc1c
fix: auto compound tests
GopherJ May 8, 2023
b6a3b37
chore: cleanup
GopherJ May 8, 2023
ffef685
fix: remove unused bot params
GopherJ May 8, 2023
4f21916
fix: increase precision
GopherJ May 8, 2023
a372a1a
chore: use real price
GopherJ May 8, 2023
5980e00
chore: use swapPercent instead
GopherJ May 8, 2023
0d81db9
Merge branch 'main' into improve/auto-compound
GopherJ May 10, 2023
c33aee9
chore: update verify docs & add shelljs
GopherJ May 10, 2023
f03f9c7
Merge remote-tracking branch 'origin/main' into improve/auto-compound
GopherJ May 16, 2023
922e77a
chore: update submodules
GopherJ May 16, 2023
3a3f074
chore: add safe owner interface
GopherJ May 16, 2023
52ca0b2
chore: use https for ethereumjs-abi
GopherJ May 16, 2023
734ae74
chore: try fix ci
GopherJ May 16, 2023
3322f6e
chore: add missing phantom enum items
GopherJ May 19, 2023
833bf75
chore: remove matching operator feature
zhoujia6139 Jun 13, 2023
8992d77
chore: allow transfer to sender address
zhoujia6139 Jun 13, 2023
efb8f0d
chore: add pause and ACL for P2P
zhoujia6139 Jun 13, 2023
4c51fac
chore: fix FUN-POOL-05: User can withdraw $APE without timeLock
zhoujia6139 Jun 15, 2023
400fae0
chore: fix bakc owner check
zhoujia6139 Jun 15, 2023
ad58564
chore: cache storage variable to save gas
zhoujia6139 Jun 15, 2023
a21896e
chore: small gas optimization
zhoujia6139 Jun 15, 2023
8fbb200
chore: fix some code style
zhoujia6139 Jun 15, 2023
7ecd60c
chore: update some storage variable to immutable to save gas.
zhoujia6139 Jun 15, 2023
16848c3
chore: cache reward amount to avoid fetch from ApeCoinStaking twice.
zhoujia6139 Jun 19, 2023
f29f946
chore: allow user set sape as collateral
zhoujia6139 Jun 20, 2023
54288cb
chore: fix lint and rename variable
zhoujia6139 Jun 20, 2023
0b0cc6a
chore: add p2p pause and test case
zhoujia6139 Jun 20, 2023
e0a113f
chore: don't need to check hf if sApe is not set as collateral
zhoujia6139 Jun 20, 2023
3cf5ed9
chore: small fix
zhoujia6139 Jun 21, 2023
317a9b9
chore: add test case and gas optimization
zhoujia6139 Jun 21, 2023
cd61586
chore: basic logic for pair staking
zhoujia6139 Jul 3, 2023
797849d
chore: pair staking test case
zhoujia6139 Jul 5, 2023
e4765ec
chore: bayc + mayc + bakc base logic and test case
zhoujia6139 Jul 6, 2023
7498945
chore: spit logic contact to reduce contract size
zhoujia6139 Jul 7, 2023
e439449
chore: add owner interface
zhoujia6139 Jul 7, 2023
9774dcf
chore: compound fee
zhoujia6139 Jul 7, 2023
ad76019
chore: fix compound fee
zhoujia6139 Jul 8, 2023
dec78f6
chore: refactor and add test case
zhoujia6139 Jul 10, 2023
a47977c
chore: add pending reward interface
zhoujia6139 Jul 10, 2023
ac73a54
chore: add multicall
zhoujia6139 Jul 11, 2023
e8404ca
chore: small optimization
zhoujia6139 Jul 12, 2023
dd4e2bb
chore: fix bakc single pool issue
zhoujia6139 Jul 12, 2023
ee5b36b
chore: gas optimization
zhoujia6139 Jul 12, 2023
610e8ed
chore: refactor and gas optimization
zhoujia6139 Jul 13, 2023
73a73ec
chore: fix p2p logic
zhoujia6139 Jul 13, 2023
91cd6f0
chore: use one-time approve
zhoujia6139 Jul 14, 2023
78cbb45
chore: rename script
zhoujia6139 Jul 14, 2023
ee177cb
chore: add comment and small optimization
zhoujia6139 Jul 14, 2023
8d0c5cb
chore: remove unused storage
zhoujia6139 Jul 17, 2023
2d382b0
chore: vault optimization and fix
zhoujia6139 Jul 18, 2023
7c82970
chore: Ape coin pool
zhoujia6139 Jul 19, 2023
7e8079e
chore: ape coin pool logic implementation
zhoujia6139 Jul 20, 2023
2a50966
chore: add pool ape staking test case.
zhoujia6139 Jul 24, 2023
63e5244
chore: small optimization
zhoujia6139 Jul 24, 2023
82e7a24
chore: add test case and fix lint
zhoujia6139 Jul 24, 2023
08c01a8
chore: remove ApeCoinPoolState
zhoujia6139 Jul 25, 2023
1c5c943
chore: refactor pool state and bakc single pool
zhoujia6139 Jul 25, 2023
f53f163
chore: add pool borrow and stake
zhoujia6139 Jul 27, 2023
4702119
chore: auto claim reward when nToken owner change.
zhoujia6139 Jul 27, 2023
725c7a7
chore: auto claim test case
zhoujia6139 Jul 27, 2023
9924c4c
chore: reduce contract size
zhoujia6139 Jul 28, 2023
4a3dce9
chore: gas optimization
zhoujia6139 Jul 28, 2023
d954418
chore: add time lock for sApe
zhoujia6139 Jul 29, 2023
1e5a776
chore: reduce contract size
zhoujia6139 Jul 31, 2023
31ea327
chore:support ape coin order as sApe balance
zhoujia6139 Aug 1, 2023
5839f00
chore: update constant hash value
zhoujia6139 Aug 1, 2023
86a15f1
chore: ApeCoin Order sApe liquidation
zhoujia6139 Aug 1, 2023
a7dc3ee
chore: small optimization
zhoujia6139 Aug 1, 2023
5843b04
chore: add query interface
zhoujia6139 Aug 2, 2023
4093145
chore: remove burn callback
zhoujia6139 Aug 2, 2023
9810d8b
chore: optimization
zhoujia6139 Aug 2, 2023
2dbac09
chore: fix compound fee.
zhoujia6139 Aug 2, 2023
26ee4df
chore: refactor query and claim pendign reward
zhoujia6139 Aug 2, 2023
6d03eec
chore: update token status query interface
zhoujia6139 Aug 3, 2023
7a4142a
chore: simplify poolTokenStatus
zhoujia6139 Aug 3, 2023
8b85cbc
chore: add comment
zhoujia6139 Aug 3, 2023
c4b0cec
chore: fix review issue and some optimization
zhoujia6139 Aug 4, 2023
cbdf4be
chore: unstake user ape staking position when hf < 1
zhoujia6139 Aug 7, 2023
eaf96e2
chore: fix review issue
zhoujia6139 Aug 7, 2023
13516b3
chore: add event definition and remove P2P contract
zhoujia6139 Aug 8, 2023
a784db1
chore: fix lint
zhoujia6139 Aug 8, 2023
940cb09
merge main branch
zhoujia6139 Aug 15, 2023
82b12d8
chore: fix typo
zhoujia6139 Aug 15, 2023
94dde81
chore: merge main
zhoujia6139 Sep 5, 2023
411eac7
chore: merge main
zhoujia6139 Sep 6, 2023
9fdd1e7
chore: merge v1 and v2 logic
zhoujia6139 Sep 6, 2023
e28bf3e
chore: keep deprecated data slot
zhoujia6139 Sep 6, 2023
57e6b26
chore: pool ape staking migration
zhoujia6139 Sep 8, 2023
c108a66
chore: p2p migration
zhoujia6139 Sep 13, 2023
02e0ee2
chore: small optimization
zhoujia6139 Sep 13, 2023
9aaaab7
chore: check ntoken owner when migration
zhoujia6139 Oct 13, 2023
88f5805
chore: merge main
zhoujia6139 Oct 13, 2023
7272557
chore: fix test case
zhoujia6139 Oct 13, 2023
0f9b99b
chore: add gas test case
zhoujia6139 Nov 9, 2023
9f0e634
chore: merge apestakingV2
zhoujia6139 Dec 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat: improve auto compound
Signed-off-by: GopherJ <alex_cj96@foxmail.com>
  • Loading branch information
GopherJ committed May 4, 2023
commit 2aca3a066de58c310a3cf51974ae24f0642050b6
12 changes: 10 additions & 2 deletions contracts/interfaces/IPoolApeStaking.sol
Original file line number Diff line number Diff line change
@@ -100,23 +100,31 @@ interface IPoolApeStaking {
* @param nftAsset Contract address of BAYC/MAYC
* @param users array of user address
* @param tokenIds array of user tokenId array
* @param minUsdcApePrice minimum usdc/ape price
* @param minWethApePrice minimum weth/ape price
*/
function claimApeAndCompound(
address nftAsset,
address[] calldata users,
uint256[][] calldata tokenIds
uint256[][] calldata tokenIds,
uint256 minUsdcApePrice,
uint256 minWethApePrice
) external;

/**
* @notice Claim user BAKC paired Ape coin reward and deposit to ape compound to get cApe, then deposit cApe to Lending pool for user
* @param nftAsset Contract address of BAYC/MAYC
* @param users array of user address
* @param _nftPairs Array of Paired BAYC/MAYC NFT's
* @param minUsdcApePrice minimum usdc/ape price
* @param minWethApePrice minimum weth/ape price
*/
function claimPairedApeAndCompound(
address nftAsset,
address[] calldata users,
ApeCoinStaking.PairNft[][] calldata _nftPairs
ApeCoinStaking.PairNft[][] calldata _nftPairs,
uint256 minUsdcApePrice,
uint256 minWethApePrice
) external;

/**
151 changes: 95 additions & 56 deletions contracts/protocol/pool/PoolApeStaking.sol
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ import "../../interfaces/IXTokenType.sol";
import "../../interfaces/INTokenApeStaking.sol";
import {ValidationLogic} from "../libraries/logic/ValidationLogic.sol";
import {IPoolAddressesProvider} from "../../interfaces/IPoolAddressesProvider.sol";
import {IPool} from "../../interfaces/IPool.sol";
import {Errors} from "../libraries/helpers/Errors.sol";
import {ReserveLogic} from "../libraries/logic/ReserveLogic.sol";
import {GenericLogic} from "../libraries/logic/GenericLogic.sol";
@@ -48,11 +49,11 @@ contract PoolApeStaking is
IERC20 internal immutable USDC;
ISwapRouter internal immutable SWAP_ROUTER;

uint256 internal constant DEFAULT_MAX_SLIPPAGE = 500; // 5%
uint256 internal constant DEFAULT_MAX_SLIPPAGE = 300; // 3%
uint24 internal immutable APE_WETH_FEE;
uint24 internal immutable WETH_USDC_FEE;
address internal immutable WETH;
address internal immutable APE_COMPOUND_TREASURY;
address internal immutable APE_COMPOUND_BOT;

event ReserveUsedAsCollateralEnabled(
address indexed reserve,
@@ -70,10 +71,13 @@ contract PoolApeStaking is
address[] transferredTokenOwners;
DataTypes.ApeCompoundStrategy[] options;
uint256 totalAmount;
uint256 totalNonDepositAmount;
uint256 compoundFee;
bytes usdcSwapPath;
bytes wethSwapPath;
uint256 totalUsdcSwapAmount;
uint256 totalWethSwapAmount;
uint256 minUsdcApePrice;
uint256 minWethApePrice;
address pUSDCAddress;
address pWETHAddress;
}

/**
@@ -89,12 +93,9 @@ contract PoolApeStaking is
address weth,
uint24 apeWethFee,
uint24 wethUsdcFee,
address apeCompoundTreasury
address apeCompoundBot
) {
require(
apeCompoundTreasury != address(0),
Errors.ZERO_ADDRESS_NOT_VALID
);
require(apeCompoundBot != address(0), Errors.ZERO_ADDRESS_NOT_VALID);
ADDRESSES_PROVIDER = provider;
APE_COMPOUND = apeCompound;
APE_COIN = apeCoin;
@@ -103,7 +104,7 @@ contract PoolApeStaking is
WETH = weth;
APE_WETH_FEE = apeWethFee;
WETH_USDC_FEE = wethUsdcFee;
APE_COMPOUND_TREASURY = apeCompoundTreasury;
APE_COMPOUND_BOT = apeCompoundBot;
}

function getRevision() internal pure virtual override returns (uint256) {
@@ -150,8 +151,6 @@ contract PoolApeStaking is
);
}
INTokenApeStaking(xTokenAddress).claimApeCoin(_nfts, msg.sender);

_checkUserHf(ps, msg.sender, true);
}

/// @inheritdoc IPoolApeStaking
@@ -455,12 +454,15 @@ contract PoolApeStaking is
function claimApeAndCompound(
address nftAsset,
address[] calldata users,
uint256[][] calldata tokenIds
uint256[][] calldata tokenIds,
uint256 minUsdcApePrice,
uint256 minWethApePrice
) external nonReentrant {
require(
users.length == tokenIds.length,
Errors.INCONSISTENT_PARAMS_LENGTH
);
require(msg.sender == APE_COMPOUND_BOT, Errors.CALLER_NOT_OPERATOR);
DataTypes.PoolStorage storage ps = poolStorage();
_checkSApeIsNotPaused(ps);

@@ -469,6 +471,8 @@ contract PoolApeStaking is
nftAsset,
users.length
);
localVar.minUsdcApePrice = minUsdcApePrice;
localVar.minWethApePrice = minWethApePrice;

for (uint256 i = 0; i < users.length; i++) {
for (uint256 j = 0; j < tokenIds[i].length; j++) {
@@ -494,19 +498,24 @@ contract PoolApeStaking is
function claimPairedApeAndCompound(
address nftAsset,
address[] calldata users,
ApeCoinStaking.PairNft[][] calldata _nftPairs
ApeCoinStaking.PairNft[][] calldata _nftPairs,
uint256 minUsdcApePrice,
uint256 minWethApePrice
) external nonReentrant {
require(
users.length == _nftPairs.length,
Errors.INCONSISTENT_PARAMS_LENGTH
);
require(msg.sender == APE_COMPOUND_BOT, Errors.CALLER_NOT_OPERATOR);
DataTypes.PoolStorage storage ps = poolStorage();

ApeStakingLocalVars memory localVar = _compoundCache(
ps,
nftAsset,
users.length
);
localVar.minUsdcApePrice = minUsdcApePrice;
localVar.minWethApePrice = minWethApePrice;

for (uint256 i = 0; i < _nftPairs.length; i++) {
localVar.transferredTokenOwners = new address[](
@@ -596,7 +605,14 @@ contract PoolApeStaking is
localVar.swapAmounts[i] = localVar.amounts[i].percentMul(
localVar.options[i].swapPercent
);
localVar.totalNonDepositAmount += localVar.swapAmounts[i];
if (
localVar.options[i].swapTokenOut ==
DataTypes.ApeCompoundTokenOut.USDC
) {
localVar.totalUsdcSwapAmount += localVar.swapAmounts[i];
} else {
localVar.totalWethSwapAmount += localVar.swapAmounts[i];
}
}
}

@@ -664,54 +680,83 @@ contract PoolApeStaking is
ApeStakingLocalVars memory localVar,
address[] calldata users
) internal {
if (localVar.totalAmount != localVar.totalNonDepositAmount) {
APE_COMPOUND.deposit(
{
uint256 totalSwapAmount = localVar.totalUsdcSwapAmount +
localVar.totalWethSwapAmount;
if (localVar.totalAmount > totalSwapAmount) {
APE_COMPOUND.deposit(
address(this),
localVar.totalAmount - totalSwapAmount
);
}
}

{
uint256 compoundFee = localVar
.totalAmount
.percentDiv(
PercentageMath.PERCENTAGE_FACTOR - localVar.compoundFee
)
.percentMul(localVar.compoundFee);
if (compoundFee > 0) {
APE_COIN.safeTransfer(APE_COMPOUND_BOT, compoundFee);
}
}

if (localVar.totalUsdcSwapAmount > 0) {
bytes memory usdcSwapPath = abi.encodePacked(
APE_COIN,
APE_WETH_FEE,
WETH,
WETH_USDC_FEE,
USDC
);
localVar.pUSDCAddress = IPool(ADDRESSES_PROVIDER.getPool())
.getReserveData(address(USDC))
.xTokenAddress;
_swapAndSupplyForUser(
ps,
address(USDC),
localVar.totalUsdcSwapAmount,
usdcSwapPath,
address(this),
localVar.totalAmount - localVar.totalNonDepositAmount
localVar.minUsdcApePrice
);
}
uint256 compoundFee = localVar
.totalAmount
.percentDiv(PercentageMath.PERCENTAGE_FACTOR - localVar.compoundFee)
.percentMul(localVar.compoundFee);
if (compoundFee > 0) {
APE_COMPOUND.deposit(APE_COMPOUND_TREASURY, compoundFee);
}

uint256 usdcPrice = _getApeRelativePrice(address(USDC), 1E6);
uint256 wethPrice = _getApeRelativePrice(address(WETH), 1E18);
localVar.usdcSwapPath = abi.encodePacked(
APE_COIN,
APE_WETH_FEE,
WETH,
WETH_USDC_FEE,
USDC
);
localVar.wethSwapPath = abi.encodePacked(APE_COIN, APE_WETH_FEE, WETH);
if (localVar.totalWethSwapAmount > 0) {
bytes memory wethSwapPath = abi.encodePacked(
APE_COIN,
APE_WETH_FEE,
WETH
);
localVar.pWETHAddress = IPool(ADDRESSES_PROVIDER.getPool())
.getReserveData(address(WETH))
.xTokenAddress;
_swapAndSupplyForUser(
ps,
address(WETH),
localVar.totalWethSwapAmount,
wethSwapPath,
address(this),
localVar.minWethApePrice
);
}

for (uint256 i = 0; i < users.length; i++) {
address swapTokenOut;
bytes memory swapPath;
uint256 price;
if (
localVar.options[i].swapTokenOut ==
DataTypes.ApeCompoundTokenOut.USDC
) {
swapTokenOut = address(USDC);
swapPath = localVar.usdcSwapPath;
price = usdcPrice;
swapTokenOut = localVar.pUSDCAddress;
} else {
swapTokenOut = address(WETH);
swapPath = localVar.wethSwapPath;
price = wethPrice;
swapTokenOut = localVar.pWETHAddress;
}
_swapAndSupplyForUser(
ps,
swapTokenOut,
localVar.swapAmounts[i],
swapPath,

IERC20(swapTokenOut).safeTransfer(
users[i],
price
localVar.swapAmounts[i]
);
_repayAndSupplyForUser(
ps,
@@ -805,12 +850,6 @@ contract PoolApeStaking is
referralCode: 0
})
);
Helpers.setAssetUsedAsCollateral(
userConfig,
ps._reserves,
asset,
onBehalfOf
);
}

function _repayForUser(
Original file line number Diff line number Diff line change
@@ -269,12 +269,6 @@ library ApeStakingLogic {
tokenId
);

uint256 apeReward = _apeCoinStaking.pendingRewards(
poolId,
address(this),
tokenId
);

(uint256 bakcTokenId, bool isPaired) = _apeCoinStaking.mainToBakc(
poolId,
tokenId
@@ -288,6 +282,6 @@ library ApeStakingLogic {
apeStakedAmount += bakcStakedAmount;
}

return apeStakedAmount + apeReward;
return apeStakedAmount;
}
}