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

Manta deploy #435

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,10 @@ set-liquidation-threshold:
set-reserve-factor:
make TASK_NAME=set-reserve-factor run-task

.PHONY: reset-all-asset-reserve-factor
reset-all-asset-reserve-factor:
make TASK_NAME=reset-all-asset-reserve-factor run-task

.PHONY: set-interest-rate-strategy
set-interest-rate-strategy:
make TASK_NAME=set-interest-rate-strategy run-task
Expand Down
85 changes: 83 additions & 2 deletions contracts/apestaking/P2PPairStaking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {IERC721} from "../dependencies/openzeppelin/contracts/IERC721.sol";
import {IERC20, SafeERC20} from "../dependencies/openzeppelin/contracts/SafeERC20.sol";
import {PercentageMath} from "../protocol/libraries/math/PercentageMath.sol";
import {SignatureChecker} from "../dependencies/looksrare/contracts/libraries/SignatureChecker.sol";
import {Errors} from "../protocol/libraries/helpers/Errors.sol";
import {IDelegateRegistry} from "../dependencies/delegation/IDelegateRegistry.sol";

contract P2PPairStaking is
Initializable,
Expand Down Expand Up @@ -47,6 +49,7 @@ contract P2PPairStaking is
address internal immutable apeCoin;
address internal immutable cApe;
ApeCoinStaking internal immutable apeCoinStaking;
address internal immutable delegateRegistry;

bytes32 internal DOMAIN_SEPARATOR;
mapping(bytes32 => ListingOrderStatus) public listingOrderStatus;
Expand All @@ -58,6 +61,8 @@ contract P2PPairStaking is
uint256 private baycMatchedCap;
uint256 private maycMatchedCap;
uint256 private bakcMatchedCap;
//asset => tokenId => delegateTo
mapping(address => mapping(uint256 => address)) tokenDelegations;

constructor(
address _bayc,
Expand All @@ -68,7 +73,8 @@ contract P2PPairStaking is
address _nBakc,
address _apeCoin,
address _cApe,
address _apeCoinStaking
address _apeCoinStaking,
address _delegateRegistry
) {
bayc = _bayc;
mayc = _mayc;
Expand All @@ -79,6 +85,7 @@ contract P2PPairStaking is
apeCoin = _apeCoin;
cApe = _cApe;
apeCoinStaking = ApeCoinStaking(_apeCoinStaking);
delegateRegistry = _delegateRegistry;
}

function initialize() public initializer {
Expand Down Expand Up @@ -117,6 +124,78 @@ contract P2PPairStaking is
}
}

function clearDelegation(address nft, uint256 tokenId) external {
require(
msg.sender == nBayc || msg.sender == nMayc || msg.sender == nBakc,
Errors.INVALID_CALLER
);
_clearDelegation(nft, tokenId);
}

function _clearDelegation(address nft, uint256 tokenId) internal {
bool delegated = (tokenDelegations[nft][tokenId] != address(0));
if (delegated) {
_updateTokenDelegation(
nft,
tokenId,
tokenDelegations[nft][tokenId],
false
);
}
}

function delegateForToken(
address nft,
uint256[] calldata tokenIds,
address delegateTo,
bool value
) external nonReentrant {
address nTokenAddress;
if (nft == bayc) {
nTokenAddress = nBayc;
} else if (nft == mayc) {
nTokenAddress = nMayc;
} else if (nft == bakc) {
nTokenAddress = nBakc;
} else {
revert("unsupported");
}
IERC721 nToken = IERC721(nTokenAddress);
for (uint256 index = 0; index < tokenIds.length; index++) {
require(
msg.sender == nToken.ownerOf(tokenIds[index]),
Errors.INVALID_CALLER
);

bool isDelegated = (tokenDelegations[nft][tokenIds[index]] !=
address(0));
require(value != isDelegated, Errors.TOKEN_ALREADY_DELEGATED);

_updateTokenDelegation(nft, tokenIds[index], delegateTo, value);
}
}

function _updateTokenDelegation(
address asset,
uint256 tokenId,
address delegateTo,
bool value
) internal {
if (value) {
tokenDelegations[asset][tokenId] = delegateTo;
} else {
delete tokenDelegations[asset][tokenId];
}

IDelegateRegistry(delegateRegistry).delegateERC721(
delegateTo,
asset,
tokenId,
"",
value
);
}

function cancelListing(
ListingOrder calldata listingOrder
) external nonReentrant {
Expand Down Expand Up @@ -326,7 +405,7 @@ contract P2PPairStaking is
apeCoinStaking.withdrawBAKC(_otherPairs, _nfts);
}
}
//5 transfer token
//5 transfer token and clear delegation
uint256 matchedCount = apeMatchedCount[order.apeToken][
order.apeTokenId
];
Expand All @@ -336,6 +415,7 @@ contract P2PPairStaking is
apeNToken,
order.apeTokenId
);
_clearDelegation(order.apeToken, order.apeTokenId);
}
apeMatchedCount[order.apeToken][order.apeTokenId] = matchedCount - 1;

Expand All @@ -349,6 +429,7 @@ contract P2PPairStaking is
nBakc,
order.bakcTokenId
);
_clearDelegation(bakc, order.bakcTokenId);
}

//6 reset ape coin listing order status
Expand Down
7 changes: 7 additions & 0 deletions contracts/interfaces/IP2PPairStaking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,11 @@ interface IP2PPairStaking {
* @param _matchingOperator The address of the new matching operator
*/
function setMatchingOperator(address _matchingOperator) external;

/**
* @notice clear delegation.
* @param nft The address of nft
* @param tokenId The token Id of nft
*/
function clearDelegation(address nft, uint256 tokenId) external;
}
10 changes: 9 additions & 1 deletion contracts/protocol/pool/DefaultReserveAuctionStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ contract DefaultReserveAuctionStrategy is IReserveAuctionStrategy {
/**
* Expressed in PRBMath.SCALE
**/
uint256 internal immutable _minPriceMultiplier;
uint256 internal _minPriceMultiplier;

/**
* Expressed in PRBMath.SCALE
Expand All @@ -47,6 +47,8 @@ contract DefaultReserveAuctionStrategy is IReserveAuctionStrategy {

uint256 internal immutable _tickLength;

address public owner;

constructor(
uint256 maxPriceMultiplier,
uint256 minExpPriceMultiplier,
Expand All @@ -61,6 +63,12 @@ contract DefaultReserveAuctionStrategy is IReserveAuctionStrategy {
_stepLinear = stepLinear;
_stepExp = stepExp;
_tickLength = tickLength;
owner = msg.sender;
}

function setMinPriceMultiplier(uint256 minPriceMultiplier) external {
require(msg.sender == owner);
_minPriceMultiplier = minPriceMultiplier;
}

function getMaxPriceMultiplier() external view returns (uint256) {
Expand Down
13 changes: 7 additions & 6 deletions contracts/protocol/pool/DefaultReserveInterestRateStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {IReserveInterestRateStrategy} from "../../interfaces/IReserveInterestRat
import {IPoolAddressesProvider} from "../../interfaces/IPoolAddressesProvider.sol";
import {IToken} from "../../interfaces/IToken.sol";
import {Errors} from "../libraries/helpers/Errors.sol";
import {MathUtils} from "../libraries/math/MathUtils.sol";

/**
* @title DefaultReserveInterestRateStrategy contract
Expand Down Expand Up @@ -103,12 +104,7 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
}

/// @inheritdoc IReserveInterestRateStrategy
function getMaxVariableBorrowRate()
external
view
override
returns (uint256)
{
function getMaxVariableBorrowRate() public view override returns (uint256) {
return
_baseVariableBorrowRate + _variableRateSlope1 + _variableRateSlope2;
}
Expand Down Expand Up @@ -173,4 +169,9 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {

return (vars.currentLiquidityRate, vars.currentVariableBorrowRate);
}

function calculateMaxYearAPY() external view returns (uint256) {
uint256 maxRate = getMaxVariableBorrowRate();
return MathUtils.calculateCompoundedInterest(maxRate, 0, 31536000);
}
}
19 changes: 19 additions & 0 deletions contracts/protocol/tokenization/NTokenApeStaking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {IRewardController} from "../../interfaces/IRewardController.sol";
import {ApeStakingLogic} from "./libraries/ApeStakingLogic.sol";
import "../../interfaces/INTokenApeStaking.sol";
import {DataTypes} from "../libraries/types/DataTypes.sol";
import {IP2PPairStaking} from "../../interfaces/IP2PPairStaking.sol";

/**
* @title ApeCoinStaking NToken
Expand Down Expand Up @@ -118,6 +119,7 @@ abstract contract NTokenApeStaking is NToken, INTokenApeStaking {
bakcNToken: getBAKCNTokenAddress()
})
);
_clearP2PDelegationInfo(tokenId);
super._transfer(from, to, tokenId, validate);
}

Expand Down Expand Up @@ -170,6 +172,13 @@ abstract contract NTokenApeStaking is NToken, INTokenApeStaking {
);
}

function setP2PPairStaking(address p2PStaking) external onlyPoolAdmin {
ApeStakingLogic.executeSetP2PPairStaking(
apeStakingDataStorage(),
p2PStaking
);
}

function apeStakingDataStorage()
internal
pure
Expand Down Expand Up @@ -231,4 +240,14 @@ abstract contract NTokenApeStaking is NToken, INTokenApeStaking {
function getBAKCNTokenAddress() internal view returns (address) {
return POOL.getReserveData(address(getBAKC())).xTokenAddress;
}

function _clearP2PDelegationInfo(uint256 tokenId) internal {
address p2PStaking = apeStakingDataStorage().p2PStaking;
if (p2PStaking != address(0)) {
IP2PPairStaking(p2PStaking).clearDelegation(
_ERC721Data.underlyingAsset,
tokenId
);
}
}
}
16 changes: 16 additions & 0 deletions contracts/protocol/tokenization/NTokenBAKC.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {INTokenApeStaking} from "../../interfaces/INTokenApeStaking.sol";
import {ApeCoinStaking} from "../../dependencies/yoga-labs/ApeCoinStaking.sol";
import {INToken} from "../../interfaces/INToken.sol";
import {IRewardController} from "../../interfaces/IRewardController.sol";
import {IP2PPairStaking} from "../../interfaces/IP2PPairStaking.sol";
import {DataTypes} from "../libraries/types/DataTypes.sol";

/**
Expand All @@ -23,6 +24,7 @@ contract NTokenBAKC is NToken {
ApeCoinStaking immutable _apeCoinStaking;
address private immutable nBAYC;
address private immutable nMAYC;
address public p2PStaking;

/**
* @dev Constructor.
Expand Down Expand Up @@ -71,13 +73,18 @@ contract NTokenBAKC is NToken {
IERC721(underlyingAsset).setApprovalForAll(address(POOL), true);
}

function setP2PPairStaking(address _p2PStaking) external onlyPoolAdmin {
p2PStaking = _p2PStaking;
}

function _transfer(
address from,
address to,
uint256 tokenId,
bool validate
) internal override {
_unStakePairedApePosition(tokenId);
_clearP2PDelegationInfo(tokenId);
super._transfer(from, to, tokenId, validate);
}

Expand Down Expand Up @@ -140,6 +147,15 @@ contract NTokenBAKC is NToken {
return positionExisted;
}

function _clearP2PDelegationInfo(uint256 tokenId) internal {
if (p2PStaking != address(0)) {
IP2PPairStaking(p2PStaking).clearDelegation(
_ERC721Data.underlyingAsset,
tokenId
);
}
}

function getXTokenType() external pure override returns (XTokenType) {
return XTokenType.NTokenBAKC;
}
Expand Down
11 changes: 11 additions & 0 deletions contracts/protocol/tokenization/libraries/ApeStakingLogic.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ library ApeStakingLogic {

struct APEStakingParameter {
uint256 unstakeIncentive;
address p2PStaking;
}
event UnstakeApeIncentiveUpdated(uint256 oldValue, uint256 newValue);

Expand Down Expand Up @@ -86,6 +87,16 @@ library ApeStakingLogic {
}
}

function executeSetP2PPairStaking(
APEStakingParameter storage stakingParameter,
address p2PStaking
) external {
address oldValue = stakingParameter.p2PStaking;
if (oldValue != p2PStaking) {
stakingParameter.p2PStaking = p2PStaking;
}
}

struct UnstakeAndRepayParams {
IPool POOL;
ApeCoinStaking _apeCoinStaking;
Expand Down
12 changes: 11 additions & 1 deletion hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,16 @@ const hardhatConfig: HardhatUserConfig = {
url: NETWORKS_RPC_URL[eEthereumNetwork.mainnet],
accounts: DEPLOYER,
},
manta: {
chainId: CHAINS_ID[eEthereumNetwork.manta],
url: NETWORKS_RPC_URL[eEthereumNetwork.manta],
accounts: DEPLOYER,
},
mantaTest: {
chainId: CHAINS_ID[eEthereumNetwork.mantaTest],
url: NETWORKS_RPC_URL[eEthereumNetwork.mantaTest],
accounts: DEPLOYER,
},
},
etherscan: {
apiKey: {
Expand All @@ -277,7 +287,6 @@ const hardhatConfig: HardhatUserConfig = {
arbitrum: ARBITRUM_ETHERSCAN_KEY,
arbitrumGoerli: ARBITRUM_GOERLI_ETHERSCAN_KEY,
arbitrumSepolia: ARBITRUM_SEPOLIA_ETHERSCAN_KEY,
parallelDev: PARALLEL_DEV_ETHERSCAN_KEY,
polygon: POLYGON_ETHERSCAN_KEY,
polygonMumbai: POLYGON_MUMBAI_ETHERSCAN_KEY,
polygonZkevm: POLYGON_ZKEVM_ETHERSCAN_KEY,
Expand All @@ -288,6 +297,7 @@ const hardhatConfig: HardhatUserConfig = {
lineaGoerli: LINEA_GOERLI_ETHERSCAN_KEY,
neon: NEON_ETHERSCAN_KEY,
parallel: PARALLEL_ETHERSCAN_KEY,
parallelDev: PARALLEL_DEV_ETHERSCAN_KEY,
},
customChains: [
eEthereumNetwork.localhost,
Expand Down
Loading
Loading