Skip to content

Commit 0dbbeef

Browse files
authored
BTT VoteERC20 (#558)
* test initialize * test setContractURI * test other functions * test propose * update * update codecov * update codecov
1 parent 49a573c commit 0dbbeef

File tree

8 files changed

+774
-0
lines changed

8 files changed

+774
-0
lines changed
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
pragma solidity ^0.8.0;
3+
4+
import "../../utils/BaseTest.sol";
5+
6+
import { TWProxy } from "contracts/infra/TWProxy.sol";
7+
import { ERC20Vote } from "contracts/base/ERC20Vote.sol";
8+
9+
contract MyVoteERC20 is VoteERC20 {
10+
function eip712NameHash() external view returns (bytes32) {
11+
return _EIP712NameHash();
12+
}
13+
14+
function eip712VersionHash() external view returns (bytes32) {
15+
return _EIP712VersionHash();
16+
}
17+
}
18+
19+
contract VoteERC20Test_Initialize is BaseTest {
20+
address payable public implementation;
21+
address payable public proxy;
22+
address public token;
23+
uint256 public initialVotingDelay;
24+
uint256 public initialVotingPeriod;
25+
uint256 public initialProposalThreshold;
26+
uint256 public initialVoteQuorumFraction;
27+
28+
event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay);
29+
event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod);
30+
event ProposalThresholdSet(uint256 oldProposalThreshold, uint256 newProposalThreshold);
31+
event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator);
32+
33+
function setUp() public override {
34+
super.setUp();
35+
36+
// Deploy voting token
37+
token = address(new ERC20Vote(deployer, "Voting VoteERC20", "VT"));
38+
39+
// Voting param initial values
40+
initialVotingDelay = 5;
41+
initialVotingPeriod = 10;
42+
initialProposalThreshold = 100;
43+
initialVoteQuorumFraction = 50;
44+
45+
// Deploy implementation.
46+
implementation = payable(address(new MyVoteERC20()));
47+
48+
// Deploy proxy pointing to implementaion.
49+
vm.prank(deployer);
50+
proxy = payable(
51+
address(
52+
new TWProxy(
53+
implementation,
54+
abi.encodeCall(
55+
VoteERC20.initialize,
56+
(
57+
NAME,
58+
CONTRACT_URI,
59+
forwarders(),
60+
token,
61+
initialVotingDelay,
62+
initialVotingPeriod,
63+
initialProposalThreshold,
64+
initialVoteQuorumFraction
65+
)
66+
)
67+
)
68+
)
69+
);
70+
}
71+
72+
function test_initialize_initializingImplementation() public {
73+
vm.expectRevert("Initializable: contract is already initialized");
74+
VoteERC20(implementation).initialize(
75+
NAME,
76+
CONTRACT_URI,
77+
forwarders(),
78+
token,
79+
initialVotingDelay,
80+
initialVotingPeriod,
81+
initialProposalThreshold,
82+
initialVoteQuorumFraction
83+
);
84+
}
85+
86+
modifier whenNotImplementation() {
87+
_;
88+
}
89+
90+
function test_initialize_proxyAlreadyInitialized() public whenNotImplementation {
91+
vm.expectRevert("Initializable: contract is already initialized");
92+
MyVoteERC20(proxy).initialize(
93+
NAME,
94+
CONTRACT_URI,
95+
forwarders(),
96+
token,
97+
initialVotingDelay,
98+
initialVotingPeriod,
99+
initialProposalThreshold,
100+
initialVoteQuorumFraction
101+
);
102+
}
103+
104+
modifier whenProxyNotInitialized() {
105+
proxy = payable(address(new TWProxy(implementation, "")));
106+
_;
107+
}
108+
109+
function test_initialize() public whenNotImplementation whenProxyNotInitialized {
110+
MyVoteERC20(proxy).initialize(
111+
NAME,
112+
CONTRACT_URI,
113+
forwarders(),
114+
token,
115+
initialVotingDelay,
116+
initialVotingPeriod,
117+
initialProposalThreshold,
118+
initialVoteQuorumFraction
119+
);
120+
121+
// check state
122+
MyVoteERC20 voteContract = MyVoteERC20(proxy);
123+
124+
assertEq(voteContract.eip712NameHash(), keccak256(bytes(NAME)));
125+
assertEq(voteContract.eip712VersionHash(), keccak256(bytes("1")));
126+
127+
address[] memory _trustedForwarders = forwarders();
128+
for (uint256 i = 0; i < _trustedForwarders.length; i++) {
129+
assertTrue(voteContract.isTrustedForwarder(_trustedForwarders[i]));
130+
}
131+
132+
assertEq(voteContract.name(), NAME);
133+
assertEq(voteContract.contractURI(), CONTRACT_URI);
134+
assertEq(voteContract.votingDelay(), initialVotingDelay);
135+
assertEq(voteContract.votingPeriod(), initialVotingPeriod);
136+
assertEq(voteContract.proposalThreshold(), initialProposalThreshold);
137+
assertEq(voteContract.quorumNumerator(), initialVoteQuorumFraction);
138+
assertEq(address(voteContract.token()), token);
139+
}
140+
141+
function test_initialize_event_VotingDelaySet() public whenNotImplementation whenProxyNotInitialized {
142+
vm.expectEmit(false, false, false, true);
143+
emit VotingDelaySet(0, initialVotingDelay);
144+
MyVoteERC20(proxy).initialize(
145+
NAME,
146+
CONTRACT_URI,
147+
forwarders(),
148+
token,
149+
initialVotingDelay,
150+
initialVotingPeriod,
151+
initialProposalThreshold,
152+
initialVoteQuorumFraction
153+
);
154+
}
155+
156+
function test_initialize_event_VotingPeriodSet() public whenNotImplementation whenProxyNotInitialized {
157+
vm.expectEmit(false, false, false, true);
158+
emit VotingPeriodSet(0, initialVotingPeriod);
159+
MyVoteERC20(proxy).initialize(
160+
NAME,
161+
CONTRACT_URI,
162+
forwarders(),
163+
token,
164+
initialVotingDelay,
165+
initialVotingPeriod,
166+
initialProposalThreshold,
167+
initialVoteQuorumFraction
168+
);
169+
}
170+
171+
function test_initialize_event_ProposalThresholdSet() public whenNotImplementation whenProxyNotInitialized {
172+
vm.expectEmit(false, false, false, true);
173+
emit ProposalThresholdSet(0, initialProposalThreshold);
174+
MyVoteERC20(proxy).initialize(
175+
NAME,
176+
CONTRACT_URI,
177+
forwarders(),
178+
token,
179+
initialVotingDelay,
180+
initialVotingPeriod,
181+
initialProposalThreshold,
182+
initialVoteQuorumFraction
183+
);
184+
}
185+
186+
function test_initialize_event_QuorumNumeratorUpdated() public whenNotImplementation whenProxyNotInitialized {
187+
vm.expectEmit(false, false, false, true);
188+
emit QuorumNumeratorUpdated(0, initialVoteQuorumFraction);
189+
MyVoteERC20(proxy).initialize(
190+
NAME,
191+
CONTRACT_URI,
192+
forwarders(),
193+
token,
194+
initialVotingDelay,
195+
initialVotingPeriod,
196+
initialProposalThreshold,
197+
initialVoteQuorumFraction
198+
);
199+
}
200+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
initialize(
2+
string memory _name,
3+
string memory _contractURI,
4+
address[] memory _trustedForwarders,
5+
address _token,
6+
uint256 _initialVotingDelay,
7+
uint256 _initialVotingPeriod,
8+
uint256 _initialProposalThreshold,
9+
uint256 _initialVoteQuorumFraction
10+
)
11+
├── when initializing the implementation contract (not proxy)
12+
│ └── it should revert ✅
13+
└── when it is a proxy to the implementation
14+
└── when it is already initialized
15+
│ └── it should revert ✅
16+
└── when it is not initialized
17+
└── it should set trustedForwarder mapping to true for all addresses in `_trustedForwarders` ✅
18+
└── it should correctly set EIP712 name hash and version hash ✅
19+
└── it should set name to `_name` input param ✅
20+
└── it should set contractURI to `_contractURI` param value ✅
21+
└── it should set votingDelay to `_initialVotingDelay` param value ✅
22+
└── it should emit VotingDelaySet event ✅
23+
└── it should set votingPeriod to `_initialVotingPeriod` param value ✅
24+
└── it should emit VotingPeriodSet event ✅
25+
└── it should set proposalThreshold to `_initialProposalThreshold` param value ✅
26+
└── it should emit ProposalThresholdSet event ✅
27+
└── it should set voting token address as the `_token` param value ✅
28+
└── it should set initial quorum numerator as `_initialVoteQuorumFraction` param value ✅
29+
└── it should emit QuorumNumeratorUpdated event ✅
30+
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
pragma solidity ^0.8.0;
3+
4+
import "../../utils/BaseTest.sol";
5+
import { IStaking721 } from "contracts/extension/interface/IStaking721.sol";
6+
import { IERC2981 } from "contracts/eip/interface/IERC2981.sol";
7+
8+
import "@openzeppelin/contracts-upgradeable/governance/GovernorUpgradeable.sol";
9+
import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol";
10+
import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol";
11+
import "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol";
12+
13+
import { TWProxy } from "contracts/infra/TWProxy.sol";
14+
import { ERC20Vote } from "contracts/base/ERC20Vote.sol";
15+
16+
contract MyVoteERC20 is VoteERC20 {}
17+
18+
contract VoteERC20Test_OtherFunctions is BaseTest {
19+
address payable public implementation;
20+
address payable public proxy;
21+
22+
address public token;
23+
uint256 public initialVotingDelay;
24+
uint256 public initialVotingPeriod;
25+
uint256 public initialProposalThreshold;
26+
uint256 public initialVoteQuorumFraction;
27+
28+
MyVoteERC20 public voteContract;
29+
30+
function setUp() public override {
31+
super.setUp();
32+
33+
// Deploy voting token
34+
vm.prank(deployer);
35+
token = address(new ERC20Vote(deployer, "Voting VoteERC20", "VT"));
36+
37+
// Voting param initial values
38+
initialVotingDelay = 1;
39+
initialVotingPeriod = 100;
40+
initialProposalThreshold = 10;
41+
initialVoteQuorumFraction = 1;
42+
43+
// Deploy implementation.
44+
implementation = payable(address(new MyVoteERC20()));
45+
46+
// Deploy proxy pointing to implementaion.
47+
vm.prank(deployer);
48+
proxy = payable(
49+
address(
50+
new TWProxy(
51+
implementation,
52+
abi.encodeCall(
53+
VoteERC20.initialize,
54+
(
55+
NAME,
56+
CONTRACT_URI,
57+
forwarders(),
58+
token,
59+
initialVotingDelay,
60+
initialVotingPeriod,
61+
initialProposalThreshold,
62+
initialVoteQuorumFraction
63+
)
64+
)
65+
)
66+
)
67+
);
68+
69+
voteContract = MyVoteERC20(proxy);
70+
}
71+
72+
function test_contractType() public {
73+
assertEq(voteContract.contractType(), bytes32("VoteERC20"));
74+
}
75+
76+
function test_contractVersion() public {
77+
assertEq(voteContract.contractVersion(), uint8(1));
78+
}
79+
80+
function test_supportsInterface() public {
81+
assertTrue(voteContract.supportsInterface(type(IERC165).interfaceId));
82+
assertTrue(voteContract.supportsInterface(type(IERC165Upgradeable).interfaceId));
83+
assertTrue(voteContract.supportsInterface(type(IERC721ReceiverUpgradeable).interfaceId));
84+
assertTrue(voteContract.supportsInterface(type(IERC1155ReceiverUpgradeable).interfaceId));
85+
assertTrue(voteContract.supportsInterface(type(IGovernorUpgradeable).interfaceId));
86+
87+
// false for other not supported interfaces
88+
assertFalse(voteContract.supportsInterface(type(IStaking721).interfaceId));
89+
}
90+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
contractType()
2+
├── it should return bytes32("VoteERC20") ✅
3+
4+
contractVersion()
5+
├── it should return uint8(1) ✅
6+
7+
supportsInterface(bytes4 interfaceId)
8+
├── it should return true for supported interface ✅
9+
├── it should return false for not supported interface ✅

0 commit comments

Comments
 (0)