Skip to content

Commit 66963be

Browse files
committed
adds tests for amount based closing config and functionality
1 parent 2478387 commit 66963be

File tree

8 files changed

+241
-7
lines changed

8 files changed

+241
-7
lines changed

src/DealNFT.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ contract DealNFT is ERC721, IDealNFT, ReentrancyGuard {
476476
return State.Claiming;
477477
} else {
478478
if(_minimumReached()) {
479-
if(_afterClosed(lastStakeTimestamp)){
479+
if(_afterClosed(lastStakeTimestamp)){ // ---
480480
return State.Cancelled;
481481
}
482482

@@ -587,7 +587,7 @@ contract DealNFT is ERC721, IDealNFT, ReentrancyGuard {
587587
* @notice Check if the minimum has been reached
588588
*/
589589
function _minimumReached() private view returns (bool) {
590-
return _totalStaked(_tokenId) >= config.dealMinimum;
590+
return config.dealMinimum > 0 && _totalStaked(_tokenId) >= config.dealMinimum;
591591
}
592592

593593
/**
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity 0.8.25;
3+
4+
import {Test, console} from "forge-std/Test.sol";
5+
import {DealNFT} from "../../src/DealNFT.sol";
6+
import {DealSetupAmountBased} from "./DealSetupAmountBased.sol";
7+
8+
contract DealNFTStatesTest is Test, DealSetupAmountBased {
9+
function setUp() public {
10+
_init();
11+
_setup();
12+
_activate();
13+
}
14+
15+
function test_State_Claiming() public {
16+
assertEq(uint256(deal.state()), uint256(DealNFT.State.Active));
17+
18+
_stake(staker1);
19+
tokenId = 0;
20+
assertEq(deal.stakedAmount(tokenId), amount);
21+
assertEq(escrowToken.balanceOf(staker1), 0);
22+
assertEq(deal.ownerOf(tokenId), staker1);
23+
assertEq(deal.totalStaked(), amount);
24+
assertEq(
25+
escrowToken.balanceOf(address(deal.getTokenBoundAccount(tokenId))),
26+
amount
27+
);
28+
29+
_stake(staker2);
30+
tokenId = 1;
31+
assertEq(deal.stakedAmount(tokenId), amount);
32+
assertEq(escrowToken.balanceOf(staker2), 0);
33+
assertEq(deal.ownerOf(tokenId), staker2);
34+
assertEq(deal.totalStaked(), amount * 2);
35+
assertEq(
36+
escrowToken.balanceOf(address(deal.getTokenBoundAccount(tokenId))),
37+
amount
38+
);
39+
assertEq(uint256(deal.state()), uint256(DealNFT.State.Claiming));
40+
}
41+
42+
function test_State_Cancelled() public {
43+
assertEq(uint256(deal.state()), uint256(DealNFT.State.Active));
44+
skip(1 weeks);
45+
_stake(staker1);
46+
_stake(staker2);
47+
assertEq(uint256(deal.state()), uint256(DealNFT.State.Claiming));
48+
skip(8 days);
49+
50+
assertEq(uint256(deal.state()), uint256(DealNFT.State.Cancelled));
51+
}
52+
53+
function test_RevertWhen_StakeClaiming() public {
54+
assertEq(uint256(deal.state()), uint256(DealNFT.State.Active));
55+
_stake(staker1);
56+
_stake(staker2);
57+
assertEq(uint256(deal.state()), uint256(DealNFT.State.Claiming));
58+
59+
vm.expectRevert(DealNFT.NotActive.selector);
60+
_stake(staker1);
61+
}
62+
63+
function test_RevertWhen_StakeAfterCancelled() public {
64+
assertEq(uint256(deal.state()), uint256(DealNFT.State.Active));
65+
skip(1 weeks);
66+
_stake(staker1);
67+
_stake(staker2);
68+
assertEq(uint256(deal.state()), uint256(DealNFT.State.Claiming));
69+
skip(8 days);
70+
assertEq(uint256(deal.state()), uint256(DealNFT.State.Cancelled));
71+
72+
vm.expectRevert(DealNFT.NotActive.selector);
73+
_stake(staker1);
74+
}
75+
76+
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity 0.8.25;
3+
4+
import {Test, console} from "forge-std/Test.sol";
5+
import {DealNFT} from "../../src/DealNFT.sol";
6+
import {AccountV3TBD} from "../../src/AccountV3TBD.sol";
7+
8+
import "multicall-authenticated/Multicall3.sol";
9+
import "erc6551/ERC6551Registry.sol";
10+
import "tokenbound/src/AccountGuardian.sol";
11+
12+
import {IERC20} from "openzeppelin/token/ERC20/IERC20.sol";
13+
import {ERC20PresetFixedSupply} from "openzeppelin/token/ERC20/presets/ERC20PresetFixedSupply.sol";
14+
import {IERC20Metadata} from "openzeppelin/token/ERC20/extensions/IERC20Metadata.sol";
15+
16+
contract DealSetupAmountBased is Test {
17+
DealNFT public deal;
18+
IERC20Metadata public escrowToken;
19+
20+
uint256 tokenId = 0;
21+
uint256 amount = 1000000;
22+
address sponsor;
23+
address treasury;
24+
address arbitrator;
25+
address staker1;
26+
address staker2;
27+
28+
function _init() internal {
29+
sponsor = vm.addr(1);
30+
treasury = vm.addr(2);
31+
arbitrator = vm.addr(3);
32+
33+
staker1 = vm.addr(4);
34+
staker2 = vm.addr(5);
35+
36+
escrowToken = new ERC20PresetFixedSupply("escrow", "escrow", 50000000, address(this));
37+
escrowToken.transfer(address(staker1), amount);
38+
escrowToken.transfer(address(staker2), amount);
39+
escrowToken.transfer(address(sponsor), amount*3);
40+
escrowToken.transfer(address(arbitrator), amount*3);
41+
42+
ERC6551Registry registry = new ERC6551Registry();
43+
Multicall3 forwarder = new Multicall3();
44+
AccountGuardian guardian = new AccountGuardian(address(this));
45+
46+
AccountV3TBD implementation = new AccountV3TBD(
47+
address(1),
48+
address(forwarder),
49+
address(registry),
50+
address(guardian)
51+
);
52+
53+
DealNFT.Configuration memory dealConfig = DealNFT.Configuration({
54+
escrowToken: address(0),
55+
sponsor: sponsor,
56+
arbitrator: arbitrator,
57+
image: "https://image.jpg",
58+
description: "",
59+
social: "",
60+
website: "",
61+
multiple: 1e18,
62+
closingDelay: 0,
63+
unstakingFee: 0,
64+
closingTime: 0,
65+
dealMinimum: 0,
66+
dealMaximum: 0,
67+
deliveryType: 0,
68+
active: false,
69+
cancelled: false,
70+
transferable: false,
71+
timeBasedClosing: false
72+
});
73+
74+
deal = new DealNFT(
75+
treasury,
76+
address(registry),
77+
payable(address(implementation)),
78+
"https://test.com/chain/1/deal/",
79+
"SurgeDealTEST",
80+
"SRGTEST",
81+
dealConfig
82+
);
83+
84+
vm.prank(treasury);
85+
deal.setArbitrator(arbitrator);
86+
87+
vm.prank(staker1);
88+
escrowToken.approve(address(deal), amount);
89+
90+
vm.prank(staker2);
91+
escrowToken.approve(address(deal), amount);
92+
93+
}
94+
95+
function _stake(address staker) internal {
96+
vm.prank(staker);
97+
deal.stake(staker, amount);
98+
}
99+
100+
function _setup() internal {
101+
vm.prank(sponsor);
102+
deal.setup(address(escrowToken), 30 minutes, 50000, 2000000, 2000000, "https://social", "https://website", "https://image", "", 1);
103+
}
104+
105+
function _configure() internal {
106+
vm.prank(sponsor);
107+
deal.configure("desc", "https://social", "https://website", 0, 0, 0, 5e18);
108+
}
109+
110+
function _activate() internal {
111+
vm.prank(sponsor);
112+
deal.activate();
113+
}
114+
115+
function _depositDeliveryTokens() internal {
116+
vm.startPrank(arbitrator);
117+
escrowToken.approve(address(deal), amount*3);
118+
deal.depositDeliveryTokens(address(escrowToken), amount*3);
119+
vm.stopPrank();
120+
}
121+
}

test/DealNFTConfigure.t.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ contract DealNFTConfigureTest is Test, DealSetup {
6060
DealNFT.Configuration memory configAfter = deal.getConfiguration();
6161
assertEq(configAfter.description, "desc");
6262
assertEq(configAfter.closingTime, block.timestamp + 2 weeks);
63-
assertEq(configAfter.dealMinimum, 0);
63+
assertEq(configAfter.dealMinimum, 1000000);
6464
assertEq(configAfter.dealMaximum, 2000000);
6565
assertEq(configAfter.transferable, false);
6666
}

test/DealNFTRecover.t.sol

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,25 @@ contract DealNFTRecoverTest is Test, DealSetup {
7878
}
7979

8080
function test_RecoverAfterClosed() public {
81-
// TODO
81+
_stake(staker1);
82+
_stake(staker2);
83+
_stake(arbitrator);
84+
85+
skip(15 days);
86+
assertEq(uint256(deal.state()), uint256(DealNFT.State.Claiming));
87+
88+
vm.expectRevert(DealNFT.MinimumReached.selector);
89+
vm.prank(staker1);
90+
deal.recover(0);
91+
92+
vm.prank(arbitrator);
93+
deal.claim();
94+
95+
assertEq(deal.totalClaimed(), amount * 2);
96+
97+
uint256 balance = escrowToken.balanceOf(arbitrator);
98+
vm.prank(arbitrator);
99+
deal.recover(2);
100+
assertEq(escrowToken.balanceOf(arbitrator), balance + amount);
82101
}
83102
}

test/DealNFTUnstake.t.sol

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,22 @@ contract DealNFTUnstakeTest is Test, DealSetup {
8787
}
8888

8989
function test_RevertWhen_UnstakeAfterClosed() public {
90-
// TODO
90+
_stake(staker1);
91+
_stake(staker2);
92+
_stake(arbitrator);
93+
94+
skip(15 days);
95+
assertEq(uint256(deal.state()), uint256(DealNFT.State.Claiming));
96+
97+
vm.expectRevert(DealNFT.MinimumReached.selector);
98+
vm.prank(staker1);
99+
deal.recover(0);
100+
101+
vm.prank(arbitrator);
102+
deal.claim();
103+
104+
vm.expectRevert(DealNFT.CannotUnstake.selector);
105+
vm.prank(arbitrator);
106+
deal.unstake(2);
91107
}
92108
}

test/DealSetup.sol

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ contract DealSetup is Test {
9090
vm.prank(staker2);
9191
escrowToken.approve(address(deal), amount);
9292

93+
vm.prank(arbitrator);
94+
escrowToken.approve(address(deal), amount);
9395
}
9496

9597
function _stake(address staker) internal {
@@ -104,7 +106,7 @@ contract DealSetup is Test {
104106

105107
function _configure() internal {
106108
vm.prank(sponsor);
107-
deal.configure("desc", "https://social", "https://website", block.timestamp + 2 weeks, 0, 2000000, 5e18);
109+
deal.configure("desc", "https://social", "https://website", block.timestamp + 2 weeks, 1000000, 2000000, 5e18);
108110
}
109111

110112
function _activate() internal {

test/Reader.t.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ contract ReaderTest is Test, DealSetup {
3434
assertEq(_deal.totalClaimed, 0);
3535
assertEq(_deal.totalStaked, 2000000);
3636
assertEq(_deal.multiple, 5e18);
37-
assertEq(_deal.dealMinimum, 0);
37+
assertEq(_deal.dealMinimum, 1000000);
3838
assertEq(_deal.dealMaximum, 2000000);
3939
assertEq(_deal.unstakingFee, 50000);
4040
assertEq(_deal.nextId, 2);

0 commit comments

Comments
 (0)