Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
O
openzeppelin-contracts-upgradeable
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
俞永鹏
openzeppelin-contracts-upgradeable
Commits
c4250c41
Commit
c4250c41
authored
May 28, 2021
by
github-actions
Browse files
Options
Browse Files
Download
Plain Diff
Merge upstream openzeppelin-contracts into upstream-patched
parents
94a29e93
adc50d46
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
176 additions
and
49 deletions
+176
-49
ERC20VotesMock.sol
contracts/mocks/ERC20VotesMock.sol
+11
-7
ERC20Votes.sol
contracts/token/ERC20/extensions/ERC20Votes.sol
+80
-29
IERC20Votes.sol
contracts/token/ERC20/extensions/IERC20Votes.sol
+1
-0
ERC20FlashMint.test.js
test/token/ERC20/extensions/ERC20FlashMint.test.js
+0
-0
ERC20Votes.test.js
test/token/ERC20/extensions/ERC20Votes.test.js
+84
-13
No files found.
contracts/mocks/ERC20VotesMock.sol
View file @
c4250c41
...
@@ -6,13 +6,17 @@ pragma solidity ^0.8.0;
...
@@ -6,13 +6,17 @@ pragma solidity ^0.8.0;
import "../token/ERC20/extensions/ERC20Votes.sol";
import "../token/ERC20/extensions/ERC20Votes.sol";
contract ERC20VotesMock is ERC20Votes {
contract ERC20VotesMock is ERC20Votes {
constructor (
constructor (string memory name, string memory symbol)
string memory name,
ERC20(name, symbol)
string memory symbol,
ERC20Permit(name)
address initialAccount,
{}
uint256 initialBalance
) payable ERC20(name, symbol) ERC20Permit(name) {
function mint(address account, uint256 amount) public {
_mint(initialAccount, initialBalance);
_mint(account, amount);
}
function burn(address account, uint256 amount) public {
_burn(account, amount);
}
}
function getChainId() external view returns (uint256) {
function getChainId() external view returns (uint256) {
...
...
contracts/token/ERC20/extensions/ERC20Votes.sol
View file @
c4250c41
...
@@ -27,6 +27,7 @@ abstract contract ERC20Votes is IERC20Votes, ERC20Permit {
...
@@ -27,6 +27,7 @@ abstract contract ERC20Votes is IERC20Votes, ERC20Permit {
mapping (address => address) private _delegates;
mapping (address => address) private _delegates;
mapping (address => Checkpoint[]) private _checkpoints;
mapping (address => Checkpoint[]) private _checkpoints;
Checkpoint[] private _totalSupplyCheckpoints;
/**
/**
* @dev Get the `pos`-th checkpoint for `account`.
* @dev Get the `pos`-th checkpoint for `account`.
...
@@ -58,13 +59,34 @@ abstract contract ERC20Votes is IERC20Votes, ERC20Permit {
...
@@ -58,13 +59,34 @@ abstract contract ERC20Votes is IERC20Votes, ERC20Permit {
}
}
/**
/**
* @dev Determine the number of votes for `account` at the begining of `blockNumber`.
* @dev Retrieve the number of votes for `account` at the end of `blockNumber`.
*
* Requirements:
*
* - `blockNumber` must have been already mined
*/
*/
function getPriorVotes(address account, uint256 blockNumber) external view override returns (uint256) {
function getPriorVotes(address account, uint256 blockNumber) external view override returns (uint256) {
require(blockNumber < block.number, "ERC20Votes::getPriorVotes: not yet determined");
require(blockNumber < block.number, "ERC20Votes: block not yet mined");
return _checkpointsLookup(_checkpoints[account], blockNumber);
}
Checkpoint[] storage ckpts = _checkpoints[account];
/**
* @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.
* It is but NOT the sum of all the delegated votes!
*
* Requirements:
*
* - `blockNumber` must have been already mined
*/
function getPriorTotalSupply(uint256 blockNumber) external view override returns (uint256) {
require(blockNumber < block.number, "ERC20Votes: block not yet mined");
return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);
}
/**
* @dev Lookup a value in a list of (sorted) checkpoints.
*/
function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {
// We run a binary search to look for the earliest checkpoint taken after `blockNumber`.
// We run a binary search to look for the earliest checkpoint taken after `blockNumber`.
//
//
// During the loop, the index of the wanted checkpoint remains in the range [low, high).
// During the loop, the index of the wanted checkpoint remains in the range [low, high).
...
@@ -103,7 +125,7 @@ abstract contract ERC20Votes is IERC20Votes, ERC20Permit {
...
@@ -103,7 +125,7 @@ abstract contract ERC20Votes is IERC20Votes, ERC20Permit {
function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s)
function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s)
public virtual override
public virtual override
{
{
require(block.timestamp <= expiry, "ERC20Votes:
:delegateBySig:
signature expired");
require(block.timestamp <= expiry, "ERC20Votes: signature expired");
address signer = ECDSA.recover(
address signer = ECDSA.recover(
_hashTypedDataV4(keccak256(abi.encode(
_hashTypedDataV4(keccak256(abi.encode(
_DELEGATION_TYPEHASH,
_DELEGATION_TYPEHASH,
...
@@ -113,11 +135,37 @@ abstract contract ERC20Votes is IERC20Votes, ERC20Permit {
...
@@ -113,11 +135,37 @@ abstract contract ERC20Votes is IERC20Votes, ERC20Permit {
))),
))),
v, r, s
v, r, s
);
);
require(nonce == _useNonce(signer), "ERC20Votes:
:delegateBySig:
invalid nonce");
require(nonce == _useNonce(signer), "ERC20Votes: invalid nonce");
return _delegate(signer, delegatee);
return _delegate(signer, delegatee);
}
}
/**
/**
* @dev snapshot the totalSupply after it has been increassed.
*/
function _mint(address account, uint256 amount) internal virtual override {
super._mint(account, amount);
require(totalSupply() <= type(uint224).max, "ERC20Votes: total supply exceeds 2**224");
_writeCheckpoint(_totalSupplyCheckpoints, add, amount);
}
/**
* @dev snapshot the totalSupply after it has been decreased.
*/
function _burn(address account, uint256 amount) internal virtual override {
super._burn(account, amount);
_writeCheckpoint(_totalSupplyCheckpoints, subtract, amount);
}
/**
* @dev move voting power when tokens are transferred.
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {
_moveVotingPower(delegates(from), delegates(to), amount);
}
/**
* @dev Change delegation for `delegator` to `delegatee`.
* @dev Change delegation for `delegator` to `delegatee`.
*/
*/
function _delegate(address delegator, address delegatee) internal virtual {
function _delegate(address delegator, address delegatee) internal virtual {
...
@@ -133,40 +181,43 @@ abstract contract ERC20Votes is IERC20Votes, ERC20Permit {
...
@@ -133,40 +181,43 @@ abstract contract ERC20Votes is IERC20Votes, ERC20Permit {
function _moveVotingPower(address src, address dst, uint256 amount) private {
function _moveVotingPower(address src, address dst, uint256 amount) private {
if (src != dst && amount > 0) {
if (src != dst && amount > 0) {
if (src != address(0)) {
if (src != address(0)) {
uint256 srcCkptLen = _checkpoints[src].length;
(uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], subtract, amount);
uint256 srcCkptOld = srcCkptLen == 0 ? 0 : _checkpoints[src][srcCkptLen - 1].votes;
emit DelegateVotesChanged(src, oldWeight, newWeight);
uint256 srcCkptNew = srcCkptOld - amount;
_writeCheckpoint(src, srcCkptLen, srcCkptOld, srcCkptNew);
}
}
if (dst != address(0)) {
if (dst != address(0)) {
uint256 dstCkptLen = _checkpoints[dst].length;
(uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], add, amount);
uint256 dstCkptOld = dstCkptLen == 0 ? 0 : _checkpoints[dst][dstCkptLen - 1].votes;
emit DelegateVotesChanged(dst, oldWeight, newWeight);
uint256 dstCkptNew = dstCkptOld + amount;
_writeCheckpoint(dst, dstCkptLen, dstCkptOld, dstCkptNew);
}
}
}
}
}
}
function _writeCheckpoint(address delegatee, uint256 pos, uint256 oldWeight, uint256 newWeight) private {
function _writeCheckpoint(
if (pos > 0 && _checkpoints[delegatee][pos - 1].fromBlock == block.number) {
Checkpoint[] storage ckpts,
_checkpoints[delegatee][pos - 1].votes = SafeCast.toUint224(newWeight);
function (uint256, uint256) view returns (uint256) op,
} else {
uint256 delta
_checkpoints[delegatee].push(Checkpoint({
)
fromBlock: SafeCast.toUint32(block.number),
private returns (uint256 oldWeight, uint256 newWeight)
votes: SafeCast.toUint224(newWeight)
{
}));
uint256 pos = ckpts.length;
}
oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;
newWeight = op(oldWeight, delta);
emit DelegateVotesChanged(delegatee, oldWeight, newWeight);
if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {
ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);
} else {
ckpts.push(Checkpoint({
fromBlock: SafeCast.toUint32(block.number),
votes: SafeCast.toUint224(newWeight)
}));
}
}
}
function _mint(address account, uint256 amount) internal virtual override {
function add(uint256 a, uint256 b) private pure returns (uint256) {
super._mint(account, amount);
return a + b;
require(totalSupply() <= type(uint224).max, "ERC20Votes: total supply exceeds 2**224");
}
}
function
_beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override
{
function
subtract(uint256 a, uint256 b) private pure returns (uint256)
{
_moveVotingPower(delegates(from), delegates(to), amount)
;
return a - b
;
}
}
}
}
contracts/token/ERC20/extensions/IERC20Votes.sol
View file @
c4250c41
...
@@ -18,6 +18,7 @@ interface IERC20Votes is IERC20 {
...
@@ -18,6 +18,7 @@ interface IERC20Votes is IERC20 {
function numCheckpoints(address account) external view returns (uint32);
function numCheckpoints(address account) external view returns (uint32);
function getCurrentVotes(address account) external view returns (uint256);
function getCurrentVotes(address account) external view returns (uint256);
function getPriorVotes(address account, uint256 blockNumber) external view returns (uint256);
function getPriorVotes(address account, uint256 blockNumber) external view returns (uint256);
function getPriorTotalSupply(uint256 blockNumber) external view returns(uint256);
function delegate(address delegatee) external;
function delegate(address delegatee) external;
function delegateBySig(address delegatee, uint nonce, uint expiry, uint8 v, bytes32 r, bytes32 s) external;
function delegateBySig(address delegatee, uint nonce, uint expiry, uint8 v, bytes32 r, bytes32 s) external;
}
}
test/token/ERC20/extensions/
draft-
ERC20FlashMint.test.js
→
test/token/ERC20/extensions/ERC20FlashMint.test.js
View file @
c4250c41
File moved
test/token/ERC20/extensions/
draft-
ERC20Votes.test.js
→
test/token/ERC20/extensions/ERC20Votes.test.js
View file @
c4250c41
...
@@ -58,11 +58,10 @@ contract('ERC20Votes', function (accounts) {
...
@@ -58,11 +58,10 @@ contract('ERC20Votes', function (accounts) {
const
name
=
'My Token'
;
const
name
=
'My Token'
;
const
symbol
=
'MTKN'
;
const
symbol
=
'MTKN'
;
const
version
=
'1'
;
const
version
=
'1'
;
const
supply
=
new
BN
(
'10000000000000000000000000'
);
const
supply
=
new
BN
(
'10000000000000000000000000'
);
beforeEach
(
async
function
()
{
beforeEach
(
async
function
()
{
this
.
token
=
await
ERC20VotesMock
.
new
(
name
,
symbol
,
holder
,
supply
);
this
.
token
=
await
ERC20VotesMock
.
new
(
name
,
symbol
);
// We get the chain id from the contract because Ganache (used for coverage) does not return the same chain id
// We get the chain id from the contract because Ganache (used for coverage) does not return the same chain id
// from within the EVM as from the JSON RPC interface.
// from within the EVM as from the JSON RPC interface.
...
@@ -85,7 +84,7 @@ contract('ERC20Votes', function (accounts) {
...
@@ -85,7 +84,7 @@ contract('ERC20Votes', function (accounts) {
it
(
'minting restriction'
,
async
function
()
{
it
(
'minting restriction'
,
async
function
()
{
const
amount
=
new
BN
(
'2'
).
pow
(
new
BN
(
'224'
));
const
amount
=
new
BN
(
'2'
).
pow
(
new
BN
(
'224'
));
await
expectRevert
(
await
expectRevert
(
ERC20VotesMock
.
new
(
name
,
symbol
,
holder
,
amount
),
this
.
token
.
mint
(
holder
,
amount
),
'ERC20Votes: total supply exceeds 2**224'
,
'ERC20Votes: total supply exceeds 2**224'
,
);
);
});
});
...
@@ -93,6 +92,7 @@ contract('ERC20Votes', function (accounts) {
...
@@ -93,6 +92,7 @@ contract('ERC20Votes', function (accounts) {
describe
(
'set delegation'
,
function
()
{
describe
(
'set delegation'
,
function
()
{
describe
(
'call'
,
function
()
{
describe
(
'call'
,
function
()
{
it
(
'delegation with balance'
,
async
function
()
{
it
(
'delegation with balance'
,
async
function
()
{
await
this
.
token
.
mint
(
holder
,
supply
);
expect
(
await
this
.
token
.
delegates
(
holder
)).
to
.
be
.
equal
(
ZERO_ADDRESS
);
expect
(
await
this
.
token
.
delegates
(
holder
)).
to
.
be
.
equal
(
ZERO_ADDRESS
);
const
{
receipt
}
=
await
this
.
token
.
delegate
(
holder
,
{
from
:
holder
});
const
{
receipt
}
=
await
this
.
token
.
delegate
(
holder
,
{
from
:
holder
});
...
@@ -116,17 +116,17 @@ contract('ERC20Votes', function (accounts) {
...
@@ -116,17 +116,17 @@ contract('ERC20Votes', function (accounts) {
});
});
it
(
'delegation without balance'
,
async
function
()
{
it
(
'delegation without balance'
,
async
function
()
{
expect
(
await
this
.
token
.
delegates
(
recipient
)).
to
.
be
.
equal
(
ZERO_ADDRESS
);
expect
(
await
this
.
token
.
delegates
(
holder
)).
to
.
be
.
equal
(
ZERO_ADDRESS
);
const
{
receipt
}
=
await
this
.
token
.
delegate
(
recipient
,
{
from
:
recipient
});
const
{
receipt
}
=
await
this
.
token
.
delegate
(
holder
,
{
from
:
holder
});
expectEvent
(
receipt
,
'DelegateChanged'
,
{
expectEvent
(
receipt
,
'DelegateChanged'
,
{
delegator
:
recipient
,
delegator
:
holder
,
fromDelegate
:
ZERO_ADDRESS
,
fromDelegate
:
ZERO_ADDRESS
,
toDelegate
:
recipient
,
toDelegate
:
holder
,
});
});
expectEvent
.
notEmitted
(
receipt
,
'DelegateVotesChanged'
);
expectEvent
.
notEmitted
(
receipt
,
'DelegateVotesChanged'
);
expect
(
await
this
.
token
.
delegates
(
recipient
)).
to
.
be
.
equal
(
recipient
);
expect
(
await
this
.
token
.
delegates
(
holder
)).
to
.
be
.
equal
(
holder
);
});
});
});
});
...
@@ -143,7 +143,7 @@ contract('ERC20Votes', function (accounts) {
...
@@ -143,7 +143,7 @@ contract('ERC20Votes', function (accounts) {
}});
}});
beforeEach
(
async
function
()
{
beforeEach
(
async
function
()
{
await
this
.
token
.
transfer
(
delegatorAddress
,
supply
,
{
from
:
holder
}
);
await
this
.
token
.
mint
(
delegatorAddress
,
supply
);
});
});
it
(
'accept signed delegation'
,
async
function
()
{
it
(
'accept signed delegation'
,
async
function
()
{
...
@@ -192,7 +192,7 @@ contract('ERC20Votes', function (accounts) {
...
@@ -192,7 +192,7 @@ contract('ERC20Votes', function (accounts) {
await
expectRevert
(
await
expectRevert
(
this
.
token
.
delegateBySig
(
delegatorAddress
,
nonce
,
MAX_UINT256
,
v
,
r
,
s
),
this
.
token
.
delegateBySig
(
delegatorAddress
,
nonce
,
MAX_UINT256
,
v
,
r
,
s
),
'ERC20Votes:
:delegateBySig:
invalid nonce'
,
'ERC20Votes: invalid nonce'
,
);
);
});
});
...
@@ -224,7 +224,7 @@ contract('ERC20Votes', function (accounts) {
...
@@ -224,7 +224,7 @@ contract('ERC20Votes', function (accounts) {
));
));
await
expectRevert
(
await
expectRevert
(
this
.
token
.
delegateBySig
(
delegatorAddress
,
nonce
+
1
,
MAX_UINT256
,
v
,
r
,
s
),
this
.
token
.
delegateBySig
(
delegatorAddress
,
nonce
+
1
,
MAX_UINT256
,
v
,
r
,
s
),
'ERC20Votes:
:delegateBySig:
invalid nonce'
,
'ERC20Votes: invalid nonce'
,
);
);
});
});
...
@@ -241,7 +241,7 @@ contract('ERC20Votes', function (accounts) {
...
@@ -241,7 +241,7 @@ contract('ERC20Votes', function (accounts) {
await
expectRevert
(
await
expectRevert
(
this
.
token
.
delegateBySig
(
delegatorAddress
,
nonce
,
expiry
,
v
,
r
,
s
),
this
.
token
.
delegateBySig
(
delegatorAddress
,
nonce
,
expiry
,
v
,
r
,
s
),
'ERC20Votes:
:delegateBySig:
signature expired'
,
'ERC20Votes: signature expired'
,
);
);
});
});
});
});
...
@@ -249,6 +249,7 @@ contract('ERC20Votes', function (accounts) {
...
@@ -249,6 +249,7 @@ contract('ERC20Votes', function (accounts) {
describe
(
'change delegation'
,
function
()
{
describe
(
'change delegation'
,
function
()
{
beforeEach
(
async
function
()
{
beforeEach
(
async
function
()
{
await
this
.
token
.
mint
(
holder
,
supply
);
await
this
.
token
.
delegate
(
holder
,
{
from
:
holder
});
await
this
.
token
.
delegate
(
holder
,
{
from
:
holder
});
});
});
...
@@ -285,6 +286,10 @@ contract('ERC20Votes', function (accounts) {
...
@@ -285,6 +286,10 @@ contract('ERC20Votes', function (accounts) {
});
});
describe
(
'transfers'
,
function
()
{
describe
(
'transfers'
,
function
()
{
beforeEach
(
async
function
()
{
await
this
.
token
.
mint
(
holder
,
supply
);
});
it
(
'no delegation'
,
async
function
()
{
it
(
'no delegation'
,
async
function
()
{
const
{
receipt
}
=
await
this
.
token
.
transfer
(
recipient
,
1
,
{
from
:
holder
});
const
{
receipt
}
=
await
this
.
token
.
transfer
(
recipient
,
1
,
{
from
:
holder
});
expectEvent
(
receipt
,
'Transfer'
,
{
from
:
holder
,
to
:
recipient
,
value
:
'1'
});
expectEvent
(
receipt
,
'Transfer'
,
{
from
:
holder
,
to
:
recipient
,
value
:
'1'
});
...
@@ -343,6 +348,10 @@ contract('ERC20Votes', function (accounts) {
...
@@ -343,6 +348,10 @@ contract('ERC20Votes', function (accounts) {
// The following tests are a adaptation of https://github.com/compound-finance/compound-protocol/blob/master/tests/Governance/CompTest.js.
// The following tests are a adaptation of https://github.com/compound-finance/compound-protocol/blob/master/tests/Governance/CompTest.js.
describe
(
'Compound test suite'
,
function
()
{
describe
(
'Compound test suite'
,
function
()
{
beforeEach
(
async
function
()
{
await
this
.
token
.
mint
(
holder
,
supply
);
});
describe
(
'balanceOf'
,
function
()
{
describe
(
'balanceOf'
,
function
()
{
it
(
'grants to initial account'
,
async
function
()
{
it
(
'grants to initial account'
,
async
function
()
{
expect
(
await
this
.
token
.
balanceOf
(
holder
)).
to
.
be
.
bignumber
.
equal
(
'10000000000000000000000000'
);
expect
(
await
this
.
token
.
balanceOf
(
holder
)).
to
.
be
.
bignumber
.
equal
(
'10000000000000000000000000'
);
...
@@ -402,7 +411,7 @@ contract('ERC20Votes', function (accounts) {
...
@@ -402,7 +411,7 @@ contract('ERC20Votes', function (accounts) {
it
(
'reverts if block number >= current block'
,
async
function
()
{
it
(
'reverts if block number >= current block'
,
async
function
()
{
await
expectRevert
(
await
expectRevert
(
this
.
token
.
getPriorVotes
(
other1
,
5
e10
),
this
.
token
.
getPriorVotes
(
other1
,
5
e10
),
'ERC20Votes:
:getPriorVotes: not yet deter
mined'
,
'ERC20Votes:
block not yet
mined'
,
);
);
});
});
...
@@ -455,4 +464,66 @@ contract('ERC20Votes', function (accounts) {
...
@@ -455,4 +464,66 @@ contract('ERC20Votes', function (accounts) {
});
});
});
});
});
});
describe
(
'getPriorTotalSupply'
,
function
()
{
beforeEach
(
async
function
()
{
await
this
.
token
.
delegate
(
holder
,
{
from
:
holder
});
});
it
(
'reverts if block number >= current block'
,
async
function
()
{
await
expectRevert
(
this
.
token
.
getPriorTotalSupply
(
5
e10
),
'ERC20Votes: block not yet mined'
,
);
});
it
(
'returns 0 if there are no checkpoints'
,
async
function
()
{
expect
(
await
this
.
token
.
getPriorTotalSupply
(
0
)).
to
.
be
.
bignumber
.
equal
(
'0'
);
});
it
(
'returns the latest block if >= last checkpoint block'
,
async
function
()
{
t1
=
await
this
.
token
.
mint
(
holder
,
supply
);
await
time
.
advanceBlock
();
await
time
.
advanceBlock
();
expect
(
await
this
.
token
.
getPriorTotalSupply
(
t1
.
receipt
.
blockNumber
)).
to
.
be
.
bignumber
.
equal
(
supply
);
expect
(
await
this
.
token
.
getPriorTotalSupply
(
t1
.
receipt
.
blockNumber
+
1
)).
to
.
be
.
bignumber
.
equal
(
supply
);
});
it
(
'returns zero if < first checkpoint block'
,
async
function
()
{
await
time
.
advanceBlock
();
const
t1
=
await
this
.
token
.
mint
(
holder
,
supply
);
await
time
.
advanceBlock
();
await
time
.
advanceBlock
();
expect
(
await
this
.
token
.
getPriorTotalSupply
(
t1
.
receipt
.
blockNumber
-
1
)).
to
.
be
.
bignumber
.
equal
(
'0'
);
expect
(
await
this
.
token
.
getPriorTotalSupply
(
t1
.
receipt
.
blockNumber
+
1
)).
to
.
be
.
bignumber
.
equal
(
'10000000000000000000000000'
);
});
it
(
'generally returns the voting balance at the appropriate checkpoint'
,
async
function
()
{
const
t1
=
await
this
.
token
.
mint
(
holder
,
supply
);
await
time
.
advanceBlock
();
await
time
.
advanceBlock
();
const
t2
=
await
this
.
token
.
burn
(
holder
,
10
);
await
time
.
advanceBlock
();
await
time
.
advanceBlock
();
const
t3
=
await
this
.
token
.
burn
(
holder
,
10
);
await
time
.
advanceBlock
();
await
time
.
advanceBlock
();
const
t4
=
await
this
.
token
.
mint
(
holder
,
20
);
await
time
.
advanceBlock
();
await
time
.
advanceBlock
();
expect
(
await
this
.
token
.
getPriorTotalSupply
(
t1
.
receipt
.
blockNumber
-
1
)).
to
.
be
.
bignumber
.
equal
(
'0'
);
expect
(
await
this
.
token
.
getPriorTotalSupply
(
t1
.
receipt
.
blockNumber
)).
to
.
be
.
bignumber
.
equal
(
'10000000000000000000000000'
);
expect
(
await
this
.
token
.
getPriorTotalSupply
(
t1
.
receipt
.
blockNumber
+
1
)).
to
.
be
.
bignumber
.
equal
(
'10000000000000000000000000'
);
expect
(
await
this
.
token
.
getPriorTotalSupply
(
t2
.
receipt
.
blockNumber
)).
to
.
be
.
bignumber
.
equal
(
'9999999999999999999999990'
);
expect
(
await
this
.
token
.
getPriorTotalSupply
(
t2
.
receipt
.
blockNumber
+
1
)).
to
.
be
.
bignumber
.
equal
(
'9999999999999999999999990'
);
expect
(
await
this
.
token
.
getPriorTotalSupply
(
t3
.
receipt
.
blockNumber
)).
to
.
be
.
bignumber
.
equal
(
'9999999999999999999999980'
);
expect
(
await
this
.
token
.
getPriorTotalSupply
(
t3
.
receipt
.
blockNumber
+
1
)).
to
.
be
.
bignumber
.
equal
(
'9999999999999999999999980'
);
expect
(
await
this
.
token
.
getPriorTotalSupply
(
t4
.
receipt
.
blockNumber
)).
to
.
be
.
bignumber
.
equal
(
'10000000000000000000000000'
);
expect
(
await
this
.
token
.
getPriorTotalSupply
(
t4
.
receipt
.
blockNumber
+
1
)).
to
.
be
.
bignumber
.
equal
(
'10000000000000000000000000'
);
});
});
});
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment