Skip to content

Commit

Permalink
test: Add NftVault tests
Browse files Browse the repository at this point in the history
  • Loading branch information
akashiceth committed Apr 25, 2023
1 parent 12a0815 commit 576aef2
Show file tree
Hide file tree
Showing 15 changed files with 9,431 additions and 8,261 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"ecmaVersion": 12
},
"rules": {
"node/no-unsupported-features/es-syntax": ["error", { "ignores": ["modules"] }]
"node/no-unsupported-features/es-syntax": ["error", { "ignores": ["modules"] }],
"prefer-const": "off"
},
"settings": {
"node": {
Expand Down
3 changes: 1 addition & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@
"**/.git": true, // this is a default value
"**/.DS_Store": true, // this is a default value
".history/**": true // this is a default value
},
"solidity.compileUsingRemoteVersion": "v0.8.9+commit.e5eed63a"
}
}
11 changes: 7 additions & 4 deletions contracts/BendNftPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ contract BendNftPool is INftPool, ReentrancyGuardUpgradeable, OwnableUpgradeable
using SafeERC20Upgradeable for IERC20Upgradeable;
using SafeERC20Upgradeable for ICoinPool;
using ApeStakingLib for IApeCoinStaking;
mapping(address => PoolState) public poolStates;

uint256 private constant APE_COIN_PRECISION = 1e18;

mapping(address => PoolState) public poolStates;
IStakeManager public override staker;
ICoinPool public coinPool;
IDelegationRegistry public delegation;
Expand Down Expand Up @@ -117,7 +119,7 @@ contract BendNftPool is INftPool, ReentrancyGuardUpgradeable, OwnableUpgradeable
);

if (pool.accumulatedRewardsPerNft > pool.rewardsDebt[tokenId_]) {
claimableRewards += (pool.accumulatedRewardsPerNft - pool.rewardsDebt[tokenId_]);
claimableRewards += (pool.accumulatedRewardsPerNft - pool.rewardsDebt[tokenId_]) / APE_COIN_PRECISION;
pool.rewardsDebt[tokenId_] = pool.accumulatedRewardsPerNft;
}
}
Expand Down Expand Up @@ -161,7 +163,8 @@ contract BendNftPool is INftPool, ReentrancyGuardUpgradeable, OwnableUpgradeable
rewardsAmount_
);
PoolState storage pool = poolStates[nft_];
pool.accumulatedRewardsPerNft += (rewardsAmount_ / pool.stakedNft.totalStaked(address(staker)));
pool.accumulatedRewardsPerNft += ((rewardsAmount_ * APE_COIN_PRECISION) /
pool.stakedNft.totalStaked(address(staker)));

coinPool.deposit(rewardsAmount_, address(this));

Expand All @@ -185,7 +188,7 @@ contract BendNftPool is INftPool, ReentrancyGuardUpgradeable, OwnableUpgradeable
for (uint256 i = 0; i < tokenIds_.length; i++) {
tokenId_ = tokenIds_[i];
if (pool.accumulatedRewardsPerNft > pool.rewardsDebt[tokenId_]) {
amount += (pool.accumulatedRewardsPerNft - pool.rewardsDebt[tokenId_]);
amount += (pool.accumulatedRewardsPerNft - pool.rewardsDebt[tokenId_]) / APE_COIN_PRECISION;
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions contracts/interfaces/INftVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ interface INftVault is IERC721Receiver {
) external;

// deposit nft
function depositNFT(
function depositNft(
address yugaNFT,
uint256[] calldata tokenIds_,
address staker
) external;

// withdraw nft
function withdrawNFT(address yugaNFT, uint256[] calldata tokenIds_) external;
function withdrawNft(address yugaNFT, uint256[] calldata tokenIds_) external;

// staker withdraw ape coin
function withdrawRefunds(address yugaNFT) external;
Expand Down
159 changes: 80 additions & 79 deletions contracts/stakednft/NftVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ contract NftVault is INftVault {
bayc = address(apeCoinStaking.bayc());
mayc = address(apeCoinStaking.mayc());
bakc = address(apeCoinStaking.bakc());
apeCoin.approve(address(apeCoinStaking), type(uint256).max);
}

function onERC721Received(
Expand Down Expand Up @@ -128,7 +129,7 @@ contract NftVault is INftVault {
}
}

function depositNFT(
function depositNft(
address nft_,
uint256[] calldata tokenIds_,
address staker_
Expand Down Expand Up @@ -359,7 +360,7 @@ contract NftVault is INftVault {
}
}

function withdrawNFT(address nft_, uint256[] calldata tokenIds_) external override onlyApe(nft_) {
function withdrawNft(address nft_, uint256[] calldata tokenIds_) external override onlyApe(nft_) {
require(tokenIds_.length > 0, "nftVault: invalid tokenIds");
if (nft_ == bayc || nft_ == mayc) {
_refundSinglePool(nft_, tokenIds_);
Expand Down Expand Up @@ -409,7 +410,7 @@ contract NftVault is INftVault {
uint256 claimedRewardsAmount_
) private {
Position storage position_ = _positions[nft_][staker_];
position_.rewardsDebt += (claimedRewardsAmount_).toInt256();
position_.rewardsDebt += (claimedRewardsAmount_ * ApeStakingLib.APE_COIN_PRECISION).toInt256();
}

function stakeBaycPool(IApeCoinStaking.SingleNft[] calldata nfts_) external override {
Expand All @@ -426,48 +427,6 @@ contract NftVault is INftVault {
_increasePosition(bayc, msg.sender, totalStakedAmount);
}

function stakeMaycPool(IApeCoinStaking.SingleNft[] calldata nfts_) external override {
uint256 totalApeCoinAmount = 0;
IApeCoinStaking.SingleNft memory singleNft_;
for (uint256 i = 0; i < nfts_.length; i++) {
singleNft_ = nfts_[i];
require(msg.sender == _stakerOf(mayc, singleNft_.tokenId), "nftVault: caller must be mayc staker");
totalApeCoinAmount += singleNft_.amount;
}
apeCoin.safeTransferFrom(msg.sender, address(this), totalApeCoinAmount);
apeCoinStaking.depositMAYC(nfts_);
_increasePosition(mayc, msg.sender, totalApeCoinAmount);
}

function stakeBakcPool(
IApeCoinStaking.PairNftDepositWithAmount[] calldata baycPairs_,
IApeCoinStaking.PairNftDepositWithAmount[] calldata maycPairs_
) external override {
uint256 totalStakedAmount = 0;
IApeCoinStaking.PairNftDepositWithAmount memory pair;
for (uint256 i = 0; i < baycPairs_.length; i++) {
pair = baycPairs_[i];
require(
msg.sender == _stakerOf(bayc, pair.mainTokenId) && msg.sender == _stakerOf(bakc, pair.bakcTokenId),
"nftVault: caller must be nft staker"
);
totalStakedAmount += pair.amount;
}

for (uint256 i = 0; i < maycPairs_.length; i++) {
pair = maycPairs_[i];
require(
msg.sender == _stakerOf(mayc, pair.mainTokenId) && msg.sender == _stakerOf(bakc, pair.bakcTokenId),
"nftVault: caller must be nft staker"
);
totalStakedAmount += pair.amount;
}
apeCoin.safeTransferFrom(msg.sender, address(this), totalStakedAmount);
apeCoinStaking.depositBAKC(baycPairs_, maycPairs_);

_increasePosition(bakc, msg.sender, totalStakedAmount);
}

function unstakeBaycPool(IApeCoinStaking.SingleNft[] calldata nfts_, address recipient_)
external
override
Expand All @@ -492,6 +451,36 @@ contract NftVault is INftVault {
_decreasePosition(nft_, msg.sender, principal);
}

function claimBaycPool(uint256[] calldata tokenIds_, address recipient_)
external
override
returns (uint256 rewards)
{
address nft_ = bayc;
for (uint256 i = 0; i < tokenIds_.length; i++) {
require(msg.sender == _stakerOf(nft_, tokenIds_[i]), "nftVault: caller must be nft staker");
}
rewards = apeCoin.balanceOf(address(recipient_));
apeCoinStaking.claimBAYC(tokenIds_, recipient_);
rewards = apeCoin.balanceOf(recipient_) - rewards;
if (rewards > 0) {
_updateRewardsDebt(nft_, msg.sender, rewards);
}
}

function stakeMaycPool(IApeCoinStaking.SingleNft[] calldata nfts_) external override {
uint256 totalApeCoinAmount = 0;
IApeCoinStaking.SingleNft memory singleNft_;
for (uint256 i = 0; i < nfts_.length; i++) {
singleNft_ = nfts_[i];
require(msg.sender == _stakerOf(mayc, singleNft_.tokenId), "nftVault: caller must be mayc staker");
totalApeCoinAmount += singleNft_.amount;
}
apeCoin.safeTransferFrom(msg.sender, address(this), totalApeCoinAmount);
apeCoinStaking.depositMAYC(nfts_);
_increasePosition(mayc, msg.sender, totalApeCoinAmount);
}

function unstakeMaycPool(IApeCoinStaking.SingleNft[] calldata nfts_, address recipient_)
external
override
Expand All @@ -516,6 +505,52 @@ contract NftVault is INftVault {
_decreasePosition(nft_, msg.sender, principal);
}

function claimMaycPool(uint256[] calldata tokenIds_, address recipient_)
external
override
returns (uint256 rewards)
{
address nft_ = mayc;
for (uint256 i = 0; i < tokenIds_.length; i++) {
require(msg.sender == _stakerOf(nft_, tokenIds_[i]), "nftVault: caller must be nft staker");
}
rewards = apeCoin.balanceOf(address(recipient_));
apeCoinStaking.claimMAYC(tokenIds_, recipient_);
rewards = apeCoin.balanceOf(recipient_) - rewards;
if (rewards > 0) {
_updateRewardsDebt(nft_, msg.sender, rewards);
}
}

function stakeBakcPool(
IApeCoinStaking.PairNftDepositWithAmount[] calldata baycPairs_,
IApeCoinStaking.PairNftDepositWithAmount[] calldata maycPairs_
) external override {
uint256 totalStakedAmount = 0;
IApeCoinStaking.PairNftDepositWithAmount memory pair;
for (uint256 i = 0; i < baycPairs_.length; i++) {
pair = baycPairs_[i];
require(
msg.sender == _stakerOf(bayc, pair.mainTokenId) && msg.sender == _stakerOf(bakc, pair.bakcTokenId),
"nftVault: caller must be nft staker"
);
totalStakedAmount += pair.amount;
}

for (uint256 i = 0; i < maycPairs_.length; i++) {
pair = maycPairs_[i];
require(
msg.sender == _stakerOf(mayc, pair.mainTokenId) && msg.sender == _stakerOf(bakc, pair.bakcTokenId),
"nftVault: caller must be nft staker"
);
totalStakedAmount += pair.amount;
}
apeCoin.safeTransferFrom(msg.sender, address(this), totalStakedAmount);
apeCoinStaking.depositBAKC(baycPairs_, maycPairs_);

_increasePosition(bakc, msg.sender, totalStakedAmount);
}

function unstakeBakcPool(
IApeCoinStaking.PairNftWithdrawWithAmount[] calldata baycPairs_,
IApeCoinStaking.PairNftWithdrawWithAmount[] calldata maycPairs_,
Expand Down Expand Up @@ -554,40 +589,6 @@ contract NftVault is INftVault {
apeCoin.safeTransfer(recipient_, principal + rewards);
}

function claimBaycPool(uint256[] calldata tokenIds_, address recipient_)
external
override
returns (uint256 rewards)
{
address nft_ = bayc;
for (uint256 i = 0; i < tokenIds_.length; i++) {
require(msg.sender == _stakerOf(nft_, tokenIds_[i]), "nftVault: caller must be nft staker");
}
rewards = apeCoin.balanceOf(address(recipient_));
apeCoinStaking.claimBAYC(tokenIds_, recipient_);
rewards = apeCoin.balanceOf(recipient_) - rewards;
if (rewards > 0) {
_updateRewardsDebt(nft_, msg.sender, rewards);
}
}

function claimMaycPool(uint256[] calldata tokenIds_, address recipient_)
external
override
returns (uint256 rewards)
{
address nft_ = mayc;
for (uint256 i = 0; i < tokenIds_.length; i++) {
require(msg.sender == _stakerOf(nft_, tokenIds_[i]), "nftVault: caller must be nft staker");
}
rewards = apeCoin.balanceOf(address(recipient_));
apeCoinStaking.claimMAYC(tokenIds_, recipient_);
rewards = apeCoin.balanceOf(recipient_) - rewards;
if (rewards > 0) {
_updateRewardsDebt(nft_, msg.sender, rewards);
}
}

function claimBakcPool(
IApeCoinStaking.PairNft[] calldata baycPairs_,
IApeCoinStaking.PairNft[] calldata maycPairs_,
Expand Down
4 changes: 2 additions & 2 deletions contracts/stakednft/StNft.sol
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ abstract contract StNft is IStakedNft, ERC721Enumerable {
for (uint256 i = 0; i < tokenIds_.length; i++) {
_nft.safeTransferFrom(_msgSender(), address(this), tokenIds_[i]);
}
nftVault.depositNFT(address(_nft), tokenIds_, staker_);
nftVault.depositNft(address(_nft), tokenIds_, staker_);
for (uint256 i = 0; i < tokenIds_.length; i++) {
// set minter
minterOf[tokenIds_[i]] = _msgSender();
Expand All @@ -84,7 +84,7 @@ abstract contract StNft is IStakedNft, ERC721Enumerable {
require(address(nftVault) == _nft.ownerOf(tokenId_), "stNFT: invalid tokenId_");
}

nftVault.withdrawNFT(address(_nft), tokenIds_);
nftVault.withdrawNft(address(_nft), tokenIds_);

for (uint256 i = 0; i < tokenIds_.length; i++) {
tokenId_ = tokenIds_[i];
Expand Down
6 changes: 3 additions & 3 deletions contracts/test/ApeCoinStaking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -634,13 +634,13 @@ contract ApeCoinStaking is Ownable {
PoolUI memory
)
{
Pool memory coinPool = pools[0];
Pool memory apeCoinPool = pools[0];
Pool memory baycPool = pools[1];
Pool memory maycPool = pools[2];
Pool memory bakcPool = pools[3];
uint256 current = getCurrentTimeRangeIndex(coinPool);
uint256 current = getCurrentTimeRangeIndex(apeCoinPool);
return (
PoolUI(0, coinPool.stakedAmount, coinPool.timeRanges[current]),
PoolUI(0, apeCoinPool.stakedAmount, apeCoinPool.timeRanges[current]),
PoolUI(1, baycPool.stakedAmount, baycPool.timeRanges[current]),
PoolUI(2, maycPool.stakedAmount, maycPool.timeRanges[current]),
PoolUI(3, bakcPool.stakedAmount, bakcPool.timeRanges[current])
Expand Down
5 changes: 0 additions & 5 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,7 @@ const config: HardhatUserConfig = {
defaultNetwork: "hardhat",
networks: {
hardhat: {
chainId: 5,
initialBaseFeePerGas: 0,
forking: {
url: NETWORKS_RPC_URL[Network.goerli],
blockNumber: 8076786,
},
allowUnlimitedContractSize: true,
},
goerli: {
Expand Down
Loading

0 comments on commit 576aef2

Please sign in to comment.