Skip to content

Commit 5dfc3a8

Browse files
committed
tmp commit
1 parent f2dc7e1 commit 5dfc3a8

File tree

11 files changed

+421
-41
lines changed

11 files changed

+421
-41
lines changed

.husky/pre-push

Lines changed: 0 additions & 6 deletions
This file was deleted.

contracts/apestaking/P2PPairStaking.sol

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import {IERC721} from "../dependencies/openzeppelin/contracts/IERC721.sol";
1313
import {IERC20, SafeERC20} from "../dependencies/openzeppelin/contracts/SafeERC20.sol";
1414
import {PercentageMath} from "../protocol/libraries/math/PercentageMath.sol";
1515
import {SignatureChecker} from "../dependencies/looksrare/contracts/libraries/SignatureChecker.sol";
16+
import {Errors} from "../protocol/libraries/helpers/Errors.sol";
17+
import {IDelegateRegistry} from "../dependencies/delegation/IDelegateRegistry.sol";
1618

1719
contract P2PPairStaking is
1820
Initializable,
@@ -47,6 +49,7 @@ contract P2PPairStaking is
4749
address internal immutable apeCoin;
4850
address internal immutable cApe;
4951
ApeCoinStaking internal immutable apeCoinStaking;
52+
address internal immutable delegateRegistry;
5053

5154
bytes32 internal DOMAIN_SEPARATOR;
5255
mapping(bytes32 => ListingOrderStatus) public listingOrderStatus;
@@ -58,6 +61,8 @@ contract P2PPairStaking is
5861
uint256 private baycMatchedCap;
5962
uint256 private maycMatchedCap;
6063
uint256 private bakcMatchedCap;
64+
//asset => tokenId => delegateTo
65+
mapping(address => mapping(uint256 => address)) tokenDelegations;
6166

6267
constructor(
6368
address _bayc,
@@ -68,7 +73,8 @@ contract P2PPairStaking is
6873
address _nBakc,
6974
address _apeCoin,
7075
address _cApe,
71-
address _apeCoinStaking
76+
address _apeCoinStaking,
77+
address _delegateRegistry
7278
) {
7379
bayc = _bayc;
7480
mayc = _mayc;
@@ -79,6 +85,7 @@ contract P2PPairStaking is
7985
apeCoin = _apeCoin;
8086
cApe = _cApe;
8187
apeCoinStaking = ApeCoinStaking(_apeCoinStaking);
88+
delegateRegistry = _delegateRegistry;
8289
}
8390

8491
function initialize() public initializer {
@@ -117,6 +124,78 @@ contract P2PPairStaking is
117124
}
118125
}
119126

127+
function clearDelegation(address nft, uint256 tokenId) external {
128+
require(
129+
msg.sender == nBayc || msg.sender == nMayc || msg.sender == nBakc,
130+
Errors.INVALID_CALLER
131+
);
132+
_clearDelegation(nft, tokenId);
133+
}
134+
135+
function _clearDelegation(address nft, uint256 tokenId) internal {
136+
bool delegated = (tokenDelegations[nft][tokenId] != address(0));
137+
if (delegated) {
138+
_updateTokenDelegation(
139+
nft,
140+
tokenId,
141+
tokenDelegations[nft][tokenId],
142+
false
143+
);
144+
}
145+
}
146+
147+
function delegateForToken(
148+
address nft,
149+
uint256[] calldata tokenIds,
150+
address delegateTo,
151+
bool value
152+
) external nonReentrant {
153+
address nTokenAddress;
154+
if (nft == bayc) {
155+
nTokenAddress = nBayc;
156+
} else if (nft == mayc) {
157+
nTokenAddress = nMayc;
158+
} else if (nft == bakc) {
159+
nTokenAddress = nBakc;
160+
} else {
161+
revert("unsupported");
162+
}
163+
IERC721 nToken = IERC721(nTokenAddress);
164+
for (uint256 index = 0; index < tokenIds.length; index++) {
165+
require(
166+
msg.sender == nToken.ownerOf(tokenIds[index]),
167+
Errors.INVALID_CALLER
168+
);
169+
170+
bool isDelegated = (tokenDelegations[nft][tokenIds[index]] !=
171+
address(0));
172+
require(value != isDelegated, Errors.TOKEN_ALREADY_DELEGATED);
173+
174+
_updateTokenDelegation(nft, tokenIds[index], delegateTo, value);
175+
}
176+
}
177+
178+
function _updateTokenDelegation(
179+
address asset,
180+
uint256 tokenId,
181+
address delegateTo,
182+
bool value
183+
) internal {
184+
if (value) {
185+
tokenDelegations[asset][tokenId] = delegateTo;
186+
} else {
187+
delete tokenDelegations[asset][tokenId];
188+
}
189+
190+
IDelegateRegistry(delegateRegistry).delegateERC721(
191+
delegateTo,
192+
asset,
193+
tokenId,
194+
"",
195+
value
196+
);
197+
}
198+
120199
function cancelListing(
121200
ListingOrder calldata listingOrder
122201
) external nonReentrant {
@@ -326,7 +405,7 @@ contract P2PPairStaking is
326405
apeCoinStaking.withdrawBAKC(_otherPairs, _nfts);
327406
}
328407
}
329-
//5 transfer token
408+
//5 transfer token and clear delegation
330409
uint256 matchedCount = apeMatchedCount[order.apeToken][
331410
order.apeTokenId
332411
];
@@ -336,6 +415,7 @@ contract P2PPairStaking is
336415
apeNToken,
337416
order.apeTokenId
338417
);
418+
_clearDelegation(order.apeToken, order.apeTokenId);
339419
}
340420
apeMatchedCount[order.apeToken][order.apeTokenId] = matchedCount - 1;
341421

@@ -349,6 +429,7 @@ contract P2PPairStaking is
349429
nBakc,
350430
order.bakcTokenId
351431
);
432+
_clearDelegation(bakc, order.bakcTokenId);
352433
}
353434

354435
//6 reset ape coin listing order status

contracts/interfaces/IP2PPairStaking.sol

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,4 +173,11 @@ interface IP2PPairStaking {
173173
* @param _matchingOperator The address of the new matching operator
174174
*/
175175
function setMatchingOperator(address _matchingOperator) external;
176+
177+
/**
178+
* @notice clear delegation.
179+
* @param nft The address of nft
180+
* @param tokenId The token Id of nft
181+
*/
182+
function clearDelegation(address nft, uint256 tokenId) external;
176183
}

contracts/protocol/tokenization/NTokenApeStaking.sol

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {IRewardController} from "../../interfaces/IRewardController.sol";
1010
import {ApeStakingLogic} from "./libraries/ApeStakingLogic.sol";
1111
import "../../interfaces/INTokenApeStaking.sol";
1212
import {DataTypes} from "../libraries/types/DataTypes.sol";
13+
import {IP2PPairStaking} from "../../interfaces/IP2PPairStaking.sol";
1314

1415
/**
1516
* @title ApeCoinStaking NToken
@@ -118,6 +119,7 @@ abstract contract NTokenApeStaking is NToken, INTokenApeStaking {
118119
bakcNToken: getBAKCNTokenAddress()
119120
})
120121
);
122+
_clearP2PDelegationInfo(tokenId);
121123
super._transfer(from, to, tokenId, validate);
122124
}
123125

@@ -170,6 +172,13 @@ abstract contract NTokenApeStaking is NToken, INTokenApeStaking {
170172
);
171173
}
172174

175+
function setP2PPairStaking(address p2PStaking) external onlyPoolAdmin {
176+
ApeStakingLogic.executeSetP2PPairStaking(
177+
apeStakingDataStorage(),
178+
p2PStaking
179+
);
180+
}
181+
173182
function apeStakingDataStorage()
174183
internal
175184
pure
@@ -231,4 +240,14 @@ abstract contract NTokenApeStaking is NToken, INTokenApeStaking {
231240
function getBAKCNTokenAddress() internal view returns (address) {
232241
return POOL.getReserveData(address(getBAKC())).xTokenAddress;
233242
}
243+
244+
function _clearP2PDelegationInfo(uint256 tokenId) internal {
245+
address p2PStaking = apeStakingDataStorage().p2PStaking;
246+
if (p2PStaking != address(0)) {
247+
IP2PPairStaking(p2PStaking).clearDelegation(
248+
_ERC721Data.underlyingAsset,
249+
tokenId
250+
);
251+
}
252+
}
234253
}

contracts/protocol/tokenization/NTokenBAKC.sol

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {INTokenApeStaking} from "../../interfaces/INTokenApeStaking.sol";
1212
import {ApeCoinStaking} from "../../dependencies/yoga-labs/ApeCoinStaking.sol";
1313
import {INToken} from "../../interfaces/INToken.sol";
1414
import {IRewardController} from "../../interfaces/IRewardController.sol";
15+
import {IP2PPairStaking} from "../../interfaces/IP2PPairStaking.sol";
1516
import {DataTypes} from "../libraries/types/DataTypes.sol";
1617

1718
/**
@@ -23,6 +24,7 @@ contract NTokenBAKC is NToken {
2324
ApeCoinStaking immutable _apeCoinStaking;
2425
address private immutable nBAYC;
2526
address private immutable nMAYC;
27+
address public p2PStaking;
2628

2729
/**
2830
* @dev Constructor.
@@ -71,13 +73,18 @@ contract NTokenBAKC is NToken {
7173
IERC721(underlyingAsset).setApprovalForAll(address(POOL), true);
7274
}
7375

76+
function setP2PPairStaking(address _p2PStaking) external onlyPoolAdmin {
77+
p2PStaking = _p2PStaking;
78+
}
79+
7480
function _transfer(
7581
address from,
7682
address to,
7783
uint256 tokenId,
7884
bool validate
7985
) internal override {
8086
_unStakePairedApePosition(tokenId);
87+
_clearP2PDelegationInfo(tokenId);
8188
super._transfer(from, to, tokenId, validate);
8289
}
8390

@@ -140,6 +147,15 @@ contract NTokenBAKC is NToken {
140147
return positionExisted;
141148
}
142149

150+
function _clearP2PDelegationInfo(uint256 tokenId) internal {
151+
if (p2PStaking != address(0)) {
152+
IP2PPairStaking(p2PStaking).clearDelegation(
153+
_ERC721Data.underlyingAsset,
154+
tokenId
155+
);
156+
}
157+
}
158+
143159
function getXTokenType() external pure override returns (XTokenType) {
144160
return XTokenType.NTokenBAKC;
145161
}

contracts/protocol/tokenization/libraries/ApeStakingLogic.sol

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ library ApeStakingLogic {
2727

2828
struct APEStakingParameter {
2929
uint256 unstakeIncentive;
30+
address p2PStaking;
3031
}
3132
event UnstakeApeIncentiveUpdated(uint256 oldValue, uint256 newValue);
3233

@@ -86,6 +87,16 @@ library ApeStakingLogic {
8687
}
8788
}
8889

90+
function executeSetP2PPairStaking(
91+
APEStakingParameter storage stakingParameter,
92+
address p2PStaking
93+
) external {
94+
address oldValue = stakingParameter.p2PStaking;
95+
if (oldValue != p2PStaking) {
96+
stakingParameter.p2PStaking = p2PStaking;
97+
}
98+
}
99+
89100
struct UnstakeAndRepayParams {
90101
IPool POOL;
91102
ApeCoinStaking _apeCoinStaking;

helpers/contracts-deployments.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ import {
164164
getAutoYieldApe,
165165
getBAYCSewerPass,
166166
getContractFactory,
167+
getDelegationRegistry,
167168
getFirstSigner,
168169
getHelperContract,
169170
getInitializableAdminUpgradeabilityProxy,
@@ -2765,6 +2766,7 @@ export const deployP2PPairStakingImpl = async (verify?: boolean) => {
27652766
const apeCoinStaking =
27662767
(await getContractAddressInDb(eContractid.ApeCoinStaking)) ||
27672768
(await deployApeCoinStaking(verify)).address;
2769+
const delegationRegistry = await getDelegationRegistry();
27682770
const args = [
27692771
allTokens.BAYC.address,
27702772
allTokens.MAYC.address,
@@ -2775,6 +2777,7 @@ export const deployP2PPairStakingImpl = async (verify?: boolean) => {
27752777
allTokens.APE.address,
27762778
allTokens.cAPE.address,
27772779
apeCoinStaking,
2780+
delegationRegistry.address,
27782781
];
27792782

27802783
return withSaveAndVerify(

market-config/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,11 @@ export const HardhatConfig: IParaSpaceConfiguration = {
169169
Chainlink: {},
170170
BendDAO: {},
171171
Stakefish: {},
172+
EnableSeaport: true,
173+
EnableLooksrare: true,
174+
EnableX2Y2: true,
175+
EnableBLUR: true,
176+
EnableApeStaking: true,
172177
// RESERVE ASSETS - CONFIG, ASSETS, BORROW RATES,
173178
ReservesConfig: {
174179
DAI: strategyDAI,

0 commit comments

Comments
 (0)