From 9e5fc4ed5b124209c286b7899ad6fc8601df3afb Mon Sep 17 00:00:00 2001 From: Sebastian Kim Date: Fri, 20 Nov 2020 00:53:11 +0900 Subject: [PATCH 1/7] Gas saving: Optimize uint types, error messages --- contracts/LockUpPool.sol | 70 +++++++++++++------------- contracts/WRNRewardPool.sol | 28 +++++------ contracts/test/WRNRewardPoolV2Test.sol | 26 +++++----- test/LockUpPoolBasic.test.js | 20 ++++---- test/WRNRewardPool.test.js | 6 +-- 5 files changed, 76 insertions(+), 74 deletions(-) diff --git a/contracts/LockUpPool.sol b/contracts/LockUpPool.sol index f162c5d..42f74ea 100644 --- a/contracts/LockUpPool.sol +++ b/contracts/LockUpPool.sol @@ -13,14 +13,14 @@ contract LockUpPool is Initializable, OwnableUpgradeSafe { using SafeERC20 for IERC20; // NOTE: didn't use actual constant variable just in case we may chage it on upgrades - uint256 public PENALTY_RATE; - uint256 public PLATFORM_FEE_RATE; - uint256 public SECONDS_IN_MONTH; + uint8 public PENALTY_RATE; + uint8 public PLATFORM_FEE_RATE; + uint24 public SECONDS_IN_MONTH; bool public emergencyMode; struct LockUp { - uint256 durationInMonths; + uint8 durationInMonths; uint256 unlockedAt; // NOTE: Potential block time manipulation by miners uint256 amount; uint256 effectiveAmount; // amount * durationBoost @@ -32,9 +32,9 @@ contract LockUpPool is Initializable, OwnableUpgradeSafe { struct UserLockUp { uint256 total; uint256 effectiveTotal; - uint256 bonusClaimed; // only used for tracking + uint256 bonusClaimed; // info uint256 bonusDebt; - uint256 lockedUpCount; // accumulative lock-up count (= length of lockUps) + uint40 lockedUpCount; // accumulative lock-up count (= length of lockUps) LockUp[] lockUps; } @@ -47,10 +47,10 @@ contract LockUpPool is Initializable, OwnableUpgradeSafe { uint256 totalClaimed; // info uint256 accBonusPerShare; // Others' Penalty = My Bonus uint256 accTotalLockUp; // info - uint256 accLockUpCount; // info - uint256 activeLockUpCount; // info - uint256 unlockedCount; // info - uint256 brokenCount; // info + uint40 accLockUpCount; // info + uint40 activeLockUpCount; // info + uint40 unlockedCount; // info + uint40 brokenCount; // info } // Token => TokenStats @@ -100,19 +100,19 @@ contract LockUpPool is Initializable, OwnableUpgradeSafe { } modifier _checkPoolExists(address tokenAddress) { - require(tokenStats[tokenAddress].maxLockUpLimit > 0, 'token pool does not exist'); + require(tokenStats[tokenAddress].maxLockUpLimit > 0, 'POOL_NOT_FOUND'); _; } modifier _checkEmergencyMode() { - require(!emergencyMode, 'not allowed during emergency mode is on'); + require(!emergencyMode, 'NOT_ALLOWED_IN_EMERGENCY'); _; } // Should be called on WRNRewardPool#addLockUpRewardPool function addLockUpPool(address tokenAddress, uint256 maxLockUpLimit) public onlyOwner { - require(tokenAddress.isContract(), 'tokeanAddress is not a contract'); - require(tokenStats[tokenAddress].maxLockUpLimit == 0, 'pool already exists'); + require(tokenAddress.isContract(), 'INVALID_TOKEN'); + require(tokenStats[tokenAddress].maxLockUpLimit == 0, 'POOL_ALREADY_EXISTS'); pools.push(tokenAddress); tokenStats[tokenAddress].maxLockUpLimit = maxLockUpLimit; @@ -135,34 +135,34 @@ contract LockUpPool is Initializable, OwnableUpgradeSafe { return durationBoost; } - function doLockUp(address tokenAddress, uint256 amount, uint256 durationInMonths) public virtual _checkPoolExists(tokenAddress) _checkEmergencyMode { - require(amount > 0, 'lock up amount must be greater than 0'); - require(durationInMonths >= 3 && durationInMonths <= 120, 'duration must be between 3 and 120 inclusive'); + function doLockUp(address tokenAddress, uint256 amount, uint8 durationInMonths) public virtual _checkPoolExists(tokenAddress) _checkEmergencyMode { + require(amount > 0, 'INVALID_AMOUNT'); + require(durationInMonths >= 3 && durationInMonths <= 120, 'INVALID_DURATION'); IERC20 token = IERC20(tokenAddress); - require(token.balanceOf(msg.sender) >= amount, 'not enough balance'); - require(token.allowance(msg.sender, address(this)) >= amount, 'not enough allowance'); - UserLockUp storage userLockUp = userLockUps[tokenAddress][msg.sender]; TokenStats storage tokenStat = tokenStats[tokenAddress]; // Max lock-up amount is restricted during the beta period - if (tokenStat.maxLockUpLimit < userLockUp.total.add(amount)) { - revert('max limit exceeded for this pool'); + if (tokenStat.maxLockUpLimit < userLockUp.total + amount) { + revert('MAX_LIMIT_EXCEEDED'); } + // NOTE: Remove duplicated checks + // require(token.balanceOf(msg.sender) >= amount, 'NOT_ENOUGH_BALANCE'); + // require(token.allowance(msg.sender, address(this)) >= amount, 'NOT_ENOUGH_ALLOWANCE'); + token.safeTransferFrom(msg.sender, address(this), amount); + // Should claim bonus before exit, otherwise `earnedBonus` will become zero afterwards claimBonus(tokenAddress); - token.safeTransferFrom(msg.sender, address(this), amount); - // Add LockUp uint256 effectiveAmount = amount.mul(_durationBoost(durationInMonths)); userLockUp.lockUps.push( LockUp( durationInMonths, - block.timestamp.add(durationInMonths.mul(SECONDS_IN_MONTH)), // unlockedAt + block.timestamp.add(durationInMonths * SECONDS_IN_MONTH), // unlockedAt amount, effectiveAmount, 0, // exitedAt @@ -174,13 +174,13 @@ contract LockUpPool is Initializable, OwnableUpgradeSafe { // Update user lockUp stats userLockUp.total = userLockUp.total.add(amount); userLockUp.effectiveTotal = userLockUp.effectiveTotal.add(effectiveAmount); - userLockUp.lockedUpCount = userLockUp.lockedUpCount.add(1); + userLockUp.lockedUpCount = userLockUp.lockedUpCount + 1; // Update TokenStats tokenStat.totalLockUp = tokenStat.totalLockUp.add(amount); tokenStat.accTotalLockUp = tokenStat.accTotalLockUp.add(amount); - tokenStat.accLockUpCount = tokenStat.accLockUpCount.add(1); - tokenStat.activeLockUpCount = tokenStat.activeLockUpCount.add(1); + tokenStat.accLockUpCount = tokenStat.accLockUpCount + 1; + tokenStat.activeLockUpCount = tokenStat.activeLockUpCount + 1; tokenStat.effectiveTotalLockUp = tokenStat.effectiveTotalLockUp.add(effectiveAmount); _updateBonusDebt(tokenAddress, msg.sender); @@ -198,8 +198,8 @@ contract LockUpPool is Initializable, OwnableUpgradeSafe { UserLockUp storage userLockUp = userLockUps[tokenAddress][msg.sender]; LockUp storage lockUp = userLockUp.lockUps[lockUpId]; - require(lockUp.exitedAt == 0, 'already exited'); - require(force || block.timestamp >= lockUp.unlockedAt, 'has not unlocked yet'); + require(lockUp.exitedAt == 0, 'ALREADY_EXITED'); + require(force || block.timestamp >= lockUp.unlockedAt, 'MUST_BE_FORCED'); // Should claim bonus before exit, otherwise `earnedBonus` will become zero afterwards claimBonus(tokenAddress); @@ -213,7 +213,7 @@ contract LockUpPool is Initializable, OwnableUpgradeSafe { fee = lockUp.amount.mul(PLATFORM_FEE_RATE).div(100); // revert(string(abi.encodePacked(penalty, '+', fee))); } else if (force) { - revert('force not necessary'); + revert('MUST_NOT_BE_FORCED'); } uint256 refundAmount = lockUp.amount.sub(penalty).sub(fee); @@ -230,11 +230,11 @@ contract LockUpPool is Initializable, OwnableUpgradeSafe { tokenStat.totalPenalty = tokenStat.totalPenalty.add(penalty); tokenStat.totalPlatformFee = tokenStat.totalPlatformFee.add(fee); - tokenStat.activeLockUpCount = tokenStat.activeLockUpCount.sub(1); + tokenStat.activeLockUpCount = tokenStat.activeLockUpCount - 1; if (penalty > 0) { - tokenStat.brokenCount = tokenStat.brokenCount.add(1); + tokenStat.brokenCount = tokenStat.brokenCount + 1; } else { - tokenStat.unlockedCount = tokenStat.unlockedCount.add(1); + tokenStat.unlockedCount = tokenStat.unlockedCount + 1; } // Update user lockUp stats @@ -318,7 +318,7 @@ contract LockUpPool is Initializable, OwnableUpgradeSafe { function lockedUpAt(address tokenAddress, address account, uint256 lockUpId) external view returns (uint256) { LockUp storage lockUp = userLockUps[tokenAddress][account].lockUps[lockUpId]; - return lockUp.unlockedAt.sub(lockUp.durationInMonths.mul(SECONDS_IN_MONTH)); + return lockUp.unlockedAt.sub(lockUp.durationInMonths * SECONDS_IN_MONTH); } function setFundAddress(address _fundAddress) external onlyOwner { diff --git a/contracts/WRNRewardPool.sol b/contracts/WRNRewardPool.sol index d20f64d..1b4f641 100644 --- a/contracts/WRNRewardPool.sol +++ b/contracts/WRNRewardPool.sol @@ -13,14 +13,14 @@ contract WRNRewardPool is LockUpPool { // NOTE: didn't use actual constant variable just in case we may chage it on upgrades uint256 public REWARD_START_BLOCK; - uint256 public REWARD_PER_BLOCK; uint256 public REWARD_END_BLOCK; uint256 public REWARD_EARLY_BONUS_END_BLOCK; - uint256 public REWARD_EARLY_BONUS_BOOST; + uint256 public REWARD_PER_BLOCK; + uint8 public REWARD_EARLY_BONUS_BOOST; - uint256 public totalMultiplier; + uint16 public totalMultiplier; struct WRNStats { - uint256 multiplier; // For WRN token distribution + uint8 multiplier; // For WRN token distribution uint256 accWRNPerShare; uint256 lastRewardBlock; } @@ -36,12 +36,12 @@ contract WRNRewardPool is LockUpPool { // Token => Account => UserWRNReward mapping (address => mapping (address => UserWRNReward)) public userWRNRewards; - event PoolAdded(address indexed tokenAddress, uint256 multiplier, uint256 timestamp); + event PoolAdded(address indexed tokenAddress, uint8 multiplier, uint256 timestamp); event WRNMinted(address indexed tokenAddress, uint256 amount, uint256 timestamp); event WRNClaimed(address indexed tokenAddress, address indexed account, uint256 amount, uint256 timestamp); function initialize(address WRNAddress, uint256 rewardStartBlock, uint256 rewardBlocks, uint256 bonusBlocks) public initializer { - require(bonusBlocks <= rewardBlocks, 'invalid parameters'); + require(bonusBlocks <= rewardBlocks, 'INVALID_PARAM'); LockUpPool.initialize(); @@ -61,8 +61,8 @@ contract WRNRewardPool is LockUpPool { // MARK: - Overiiding LockUpPool - function addLockUpRewardPool(address tokenAddress, uint256 multiplier, uint256 maxLockUpLimit, bool shouldUpdate) external onlyOwner { - require(multiplier >= 0, 'multiplier must be greater than or equal to 0'); + function addLockUpRewardPool(address tokenAddress, uint8 multiplier, uint256 maxLockUpLimit, bool shouldUpdate) external onlyOwner { + require(multiplier >= 0, 'INVALID_MULTIPLIER'); if(shouldUpdate) { // NOTE: This could fail with out-of-gas if too many tokens are added. @@ -79,13 +79,13 @@ contract WRNRewardPool is LockUpPool { addLockUpPool(tokenAddress, maxLockUpLimit); wrnStats[tokenAddress].multiplier = multiplier; - totalMultiplier = totalMultiplier.add(multiplier); + totalMultiplier = totalMultiplier + multiplier; emit PoolAdded(tokenAddress, multiplier, block.timestamp); } - function updatePoolMultiplier(address tokenAddress, uint256 multiplier, bool shouldUpdate) external onlyOwner { - require(multiplier >= 1, 'multiplier must be greater than or equal to 1'); + function updatePoolMultiplier(address tokenAddress, uint8 multiplier, bool shouldUpdate) external onlyOwner { + require(multiplier >= 0, 'INVALID_MULTIPLIER'); if(shouldUpdate) { // NOTE: This could fail with out-of-gas if too many tokens are added. @@ -96,10 +96,10 @@ contract WRNRewardPool is LockUpPool { // users can temporarily withdraw a bigger WRN reward than they actually have // (caused by smaller `totalMultiplier` => bigger `accWRNPerShare`) - revert('cannot update to a smaller value without updating all pools'); + revert('UPDATE_ALL_REQUIRED'); } - totalMultiplier = totalMultiplier.sub(wrnStats[tokenAddress].multiplier).add(multiplier); + totalMultiplier = totalMultiplier - wrnStats[tokenAddress].multiplier + multiplier; wrnStats[tokenAddress].multiplier = multiplier; } @@ -108,7 +108,7 @@ contract WRNRewardPool is LockUpPool { .mul(userLockUps[tokenAddress][account].effectiveTotal).div(1e18); } - function doLockUp(address tokenAddress, uint256 amount, uint256 durationInMonths) public override { + function doLockUp(address tokenAddress, uint256 amount, uint8 durationInMonths) public override { // Should claim WRN before exit, otherwise `pendingWRN` will become zero afterwards claimWRN(tokenAddress); diff --git a/contracts/test/WRNRewardPoolV2Test.sol b/contracts/test/WRNRewardPoolV2Test.sol index 51c4ce6..3064fdf 100644 --- a/contracts/test/WRNRewardPoolV2Test.sol +++ b/contracts/test/WRNRewardPoolV2Test.sol @@ -22,11 +22,11 @@ contract WRNRewardPoolV2Test is LockUpPool { uint256 public REWARD_PER_BLOCK; uint256 public REWARD_END_BLOCK; uint256 public REWARD_EARLY_BONUS_END_BLOCK; - uint256 public REWARD_EARLY_BONUS_BOOST; + uint8 public REWARD_EARLY_BONUS_BOOST; - uint256 public totalMultiplier; + uint16 public totalMultiplier; struct WRNStats { - uint256 multiplier; // For WRN token distribution + uint8 multiplier; // For WRN token distribution uint256 accWRNPerShare; uint256 lastRewardBlock; } @@ -42,7 +42,7 @@ contract WRNRewardPoolV2Test is LockUpPool { // Token => Account => UserWRNReward mapping (address => mapping (address => UserWRNReward)) public userWRNRewards; - event PoolAdded(address indexed tokenAddress, uint256 multiplier, uint256 timestamp); + event PoolAdded(address indexed tokenAddress, uint8 multiplier, uint256 timestamp); event WRNMinted(address indexed tokenAddress, uint256 amount, uint256 timestamp); event WRNClaimed(address indexed tokenAddress, address indexed account, uint256 amount, uint256 timestamp); @@ -50,6 +50,8 @@ contract WRNRewardPoolV2Test is LockUpPool { uint256 public varAdded; function initialize(address WRNAddress, uint256 rewardStartBlock, uint256 rewardBlocks, uint256 bonusBlocks) public initializer { + require(bonusBlocks <= rewardBlocks, 'INVALID_PARAM'); + LockUpPool.initialize(); WRNToken = ERC20PresetMinterPauserUpgradeSafe(WRNAddress); @@ -68,8 +70,8 @@ contract WRNRewardPoolV2Test is LockUpPool { // MARK: - Overiiding LockUpPool - function addLockUpRewardPool(address tokenAddress, uint256 multiplier, uint256 maxLockUpLimit, bool shouldUpdate) external onlyOwner { - require(multiplier >= 0, 'multiplier must be greater than or equal to 0'); + function addLockUpRewardPool(address tokenAddress, uint8 multiplier, uint256 maxLockUpLimit, bool shouldUpdate) external onlyOwner { + require(multiplier >= 0, 'INVALID_MULTIPLIER'); if(shouldUpdate) { // NOTE: This could fail with out-of-gas if too many tokens are added. @@ -86,13 +88,13 @@ contract WRNRewardPoolV2Test is LockUpPool { addLockUpPool(tokenAddress, maxLockUpLimit); wrnStats[tokenAddress].multiplier = multiplier; - totalMultiplier = totalMultiplier.add(multiplier); + totalMultiplier = totalMultiplier + multiplier; emit PoolAdded(tokenAddress, multiplier, block.timestamp); } - function updatePoolMultiplier(address tokenAddress, uint256 multiplier, bool shouldUpdate) external onlyOwner { - require(multiplier >= 1, 'multiplier must be greater than or equal to 1'); + function updatePoolMultiplier(address tokenAddress, uint8 multiplier, bool shouldUpdate) external onlyOwner { + require(multiplier >= 0, 'INVALID_MULTIPLIER'); if(shouldUpdate) { // NOTE: This could fail with out-of-gas if too many tokens are added. @@ -103,10 +105,10 @@ contract WRNRewardPoolV2Test is LockUpPool { // users can temporarily withdraw a bigger WRN reward than they actually have // (caused by smaller `totalMultiplier` => bigger `accWRNPerShare`) - revert('cannot update to a smaller value without updating all pools'); + revert('UPDATE_ALL_REQUIRED'); } - totalMultiplier = totalMultiplier.sub(wrnStats[tokenAddress].multiplier).add(multiplier); + totalMultiplier = totalMultiplier - wrnStats[tokenAddress].multiplier + multiplier; wrnStats[tokenAddress].multiplier = multiplier; } @@ -120,7 +122,7 @@ contract WRNRewardPoolV2Test is LockUpPool { .mul(userLockUps[tokenAddress][account].effectiveTotal).div(1e18); } - function doLockUp(address tokenAddress, uint256 amount, uint256 durationInMonths) public override { + function doLockUp(address tokenAddress, uint256 amount, uint8 durationInMonths) public override { // Should claim WRN before exit, otherwise `pendingWRN` will become zero afterwards claimWRN(tokenAddress); diff --git a/test/LockUpPoolBasic.test.js b/test/LockUpPoolBasic.test.js index fffcc8e..4b2b55d 100644 --- a/test/LockUpPoolBasic.test.js +++ b/test/LockUpPoolBasic.test.js @@ -41,12 +41,12 @@ contract('Basic contract functionality', ([creator, alice]) => { await this.wbtc.initialize('Wrapped BTC', 'wBTC', 8, 10000); await this.hunt.approve(this.lockUpPool.address, 1000, { from: creator }); - await expectRevert(this.lockUpPool.doLockUp(this.wbtc.address, 1000, 9, { from: creator }), 'token pool does not exist'); + await expectRevert(this.lockUpPool.doLockUp(this.wbtc.address, 1000, 9, { from: creator }), 'POOL_NOT_FOUND'); }); it('should fail on lack of balance or allowance', async () => { - await expectRevert(this.lockUpPool.doLockUp(this.hunt.address, 10001, 9, { from: creator }), 'not enough balance'); - await expectRevert(this.lockUpPool.doLockUp(this.hunt.address, 1000, 9, { from: creator }), 'not enough allowance'); + await expectRevert(this.lockUpPool.doLockUp(this.hunt.address, 10001, 9, { from: creator }), 'SafeERC20: low-level call failed'); + await expectRevert(this.lockUpPool.doLockUp(this.hunt.address, 1000, 9, { from: creator }), 'SafeERC20: low-level call failed'); }); it('lock up asset properly', async () => { @@ -87,12 +87,12 @@ contract('Basic contract functionality', ([creator, alice]) => { await expectRevert( this.lockUpPool.doLockUp(this.hunt.address, 1000, 121, { from: creator }), - 'duration must be between 3 and 120 inclusive' + 'INVALID_DURATION' ); await expectRevert( this.lockUpPool.doLockUp(this.hunt.address, 1000, 2, { from: creator }), - 'duration must be between 3 and 120 inclusive' + 'INVALID_DURATION' ); }); @@ -182,7 +182,7 @@ contract('Basic contract functionality', ([creator, alice]) => { await expectRevert( this.lockUpPool.exit(this.hunt.address, 0, false, { from: creator }), - 'already exited' + 'ALREADY_EXITED' ); assert.equal((await this.hunt.balanceOf(creator, { from: creator })).valueOf(), 10000); @@ -233,7 +233,7 @@ contract('Basic contract functionality', ([creator, alice]) => { await expectRevert( this.lockUpPool.doLockUp(this.hunt.address, 1, 3), - 'max limit exceeded for this pool' + 'MAX_LIMIT_EXCEEDED' ); }); @@ -253,7 +253,7 @@ contract('Basic contract functionality', ([creator, alice]) => { await this.lockUpPool.setEmergencyMode(true); await expectRevert( this.lockUpPool.doLockUp(this.hunt.address, 1000, 3), - 'not allowed during emergency mode is on' + 'NOT_ALLOWED_IN_EMERGENCY' ); }); @@ -263,7 +263,7 @@ contract('Basic contract functionality', ([creator, alice]) => { await this.lockUpPool.setEmergencyMode(true); await expectRevert( this.lockUpPool.exit(this.hunt.address, 0, true), - 'not allowed during emergency mode is on' + 'NOT_ALLOWED_IN_EMERGENCY' ); }); @@ -279,7 +279,7 @@ contract('Basic contract functionality', ([creator, alice]) => { await this.lockUpPool.setEmergencyMode(true); await expectRevert( this.lockUpPool.exit(this.hunt.address, 0, true, { from: creator }), - 'not allowed during emergency mode is on' + 'NOT_ALLOWED_IN_EMERGENCY' ); }); }); diff --git a/test/WRNRewardPool.test.js b/test/WRNRewardPool.test.js index ae4ef3a..5449d0f 100644 --- a/test/WRNRewardPool.test.js +++ b/test/WRNRewardPool.test.js @@ -51,7 +51,7 @@ contract('WRN Reward Pool Test', ([creator, alice, bob]) => { await this.wrnRewardPool.setEmergencyMode(true); await expectRevert( this.wrnRewardPool.doLockUp(this.hunt.address, 1000, 3), - 'not allowed during emergency mode is on' + 'NOT_ALLOWED_IN_EMERGENCY' ); }); @@ -59,7 +59,7 @@ contract('WRN Reward Pool Test', ([creator, alice, bob]) => { this.eth = await ERC20Token.new({ from: creator }); await this.eth.initialize('Ethereum', 'ETH', 18, toBN(1000)); - await expectRevert(this.wrnRewardPool.updatePool(this.eth.address), 'token pool does not exist'); + await expectRevert(this.wrnRewardPool.updatePool(this.eth.address), 'POOL_NOT_FOUND'); }); it('should not have any pending WRN for non-existing pool', async () => { @@ -179,7 +179,7 @@ contract('WRN Reward Pool Test', ([creator, alice, bob]) => { it('should fail on updating to a smaller multiplier without updating all pool', async () => { await expectRevert( this.wrnRewardPool.updatePoolMultiplier(this.hunt.address, 1, false), - 'cannot update to a smaller value without updating all pools' + 'UPDATE_ALL_REQUIRED' ); }); From 4390525fcb230637320e4d5081db08874b3717f1 Mon Sep 17 00:00:00 2001 From: Sebastian Kim Date: Fri, 20 Nov 2020 01:03:02 +0900 Subject: [PATCH 2/7] Add user accumulative total lock-up value --- contracts/LockUpPool.sol | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contracts/LockUpPool.sol b/contracts/LockUpPool.sol index 42f74ea..8b0991e 100644 --- a/contracts/LockUpPool.sol +++ b/contracts/LockUpPool.sol @@ -32,6 +32,7 @@ contract LockUpPool is Initializable, OwnableUpgradeSafe { struct UserLockUp { uint256 total; uint256 effectiveTotal; + uint256 accTotal; // info uint256 bonusClaimed; // info uint256 bonusDebt; uint40 lockedUpCount; // accumulative lock-up count (= length of lockUps) @@ -173,6 +174,7 @@ contract LockUpPool is Initializable, OwnableUpgradeSafe { // Update user lockUp stats userLockUp.total = userLockUp.total.add(amount); + userLockUp.accTotal = userLockUp.accTotal.add(amount); userLockUp.effectiveTotal = userLockUp.effectiveTotal.add(effectiveAmount); userLockUp.lockedUpCount = userLockUp.lockedUpCount + 1; From be18ba811bf2c56908ae111a3779db0e3bb2e3cc Mon Sep 17 00:00:00 2001 From: Sebastian Kim Date: Fri, 20 Nov 2020 14:16:28 +0900 Subject: [PATCH 3/7] Steemhunt/neverlose.money-web#99 - Remove unecessary records (penalty, fee, totalPlatformFee, totalClaimed) from storage --- contracts/LockUpPool.sol | 29 +++++------------------- test/LockUpPoolBasic.test.js | 42 +++++++++-------------------------- test/LockUpPoolDetail.test.js | 32 +++++++++++++------------- test/helpers/LogHelpers.js | 27 ++++++++++++++-------- 4 files changed, 49 insertions(+), 81 deletions(-) diff --git a/contracts/LockUpPool.sol b/contracts/LockUpPool.sol index 8b0991e..26cd4f9 100644 --- a/contracts/LockUpPool.sol +++ b/contracts/LockUpPool.sol @@ -25,8 +25,6 @@ contract LockUpPool is Initializable, OwnableUpgradeSafe { uint256 amount; uint256 effectiveAmount; // amount * durationBoost uint256 exitedAt; - uint256 penalty; - uint256 fee; } struct UserLockUp { @@ -41,12 +39,10 @@ contract LockUpPool is Initializable, OwnableUpgradeSafe { struct TokenStats { uint256 maxLockUpLimit; - uint256 totalLockUp; // info + uint256 totalLockUp; uint256 effectiveTotalLockUp; // sum(amount * durationBoost) - uint256 totalPenalty; // info - uint256 totalPlatformFee; // info - uint256 totalClaimed; // info uint256 accBonusPerShare; // Others' Penalty = My Bonus + uint256 totalPenalty; // info uint256 accTotalLockUp; // info uint40 accLockUpCount; // info uint40 activeLockUpCount; // info @@ -166,9 +162,7 @@ contract LockUpPool is Initializable, OwnableUpgradeSafe { block.timestamp.add(durationInMonths * SECONDS_IN_MONTH), // unlockedAt amount, effectiveAmount, - 0, // exitedAt - 0, // penalty - 0 // fee + 0 // exitedAt ) ); @@ -222,15 +216,12 @@ contract LockUpPool is Initializable, OwnableUpgradeSafe { // Update lockUp lockUp.exitedAt = block.timestamp; - lockUp.penalty = penalty; - lockUp.fee = fee; // Update token stats TokenStats storage tokenStat = tokenStats[tokenAddress]; tokenStat.totalLockUp = tokenStat.totalLockUp.sub(lockUp.amount); tokenStat.effectiveTotalLockUp = tokenStat.effectiveTotalLockUp.sub(lockUp.effectiveAmount); tokenStat.totalPenalty = tokenStat.totalPenalty.add(penalty); - tokenStat.totalPlatformFee = tokenStat.totalPlatformFee.add(fee); tokenStat.activeLockUpCount = tokenStat.activeLockUpCount - 1; if (penalty > 0) { @@ -278,16 +269,12 @@ contract LockUpPool is Initializable, OwnableUpgradeSafe { return; } - TokenStats storage tokenStat = tokenStats[tokenAddress]; UserLockUp storage userLockUp = userLockUps[tokenAddress][msg.sender]; // Update user lockUp stats userLockUp.bonusClaimed = userLockUp.bonusClaimed.add(amount); _updateBonusDebt(tokenAddress, msg.sender); - // Update token stats - tokenStat.totalClaimed = tokenStat.totalClaimed.add(amount); - IERC20(tokenAddress).safeTransfer(msg.sender, amount); emit BonusClaimed(tokenAddress, msg.sender, amount, block.timestamp); @@ -295,15 +282,11 @@ contract LockUpPool is Initializable, OwnableUpgradeSafe { // MARK: - Utility view functions - function totalClaimableBonus(address tokenAddress) external view returns (uint256) { - return tokenStats[tokenAddress].totalPenalty.sub(tokenStats[tokenAddress].totalClaimed); - } - function poolCount() external view returns(uint256) { return pools.length; } - function getLockUp(address tokenAddress, address account, uint256 lockUpId) external view returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256) { + function getLockUp(address tokenAddress, address account, uint256 lockUpId) external view returns (uint8, uint256, uint256, uint256, uint256) { LockUp storage lockUp = userLockUps[tokenAddress][account].lockUps[lockUpId]; return ( @@ -311,9 +294,7 @@ contract LockUpPool is Initializable, OwnableUpgradeSafe { lockUp.unlockedAt, lockUp.amount, lockUp.effectiveAmount, - lockUp.exitedAt, - lockUp.penalty, - lockUp.fee + lockUp.exitedAt ); } diff --git a/test/LockUpPoolBasic.test.js b/test/LockUpPoolBasic.test.js index 4b2b55d..b4563cf 100644 --- a/test/LockUpPoolBasic.test.js +++ b/test/LockUpPoolBasic.test.js @@ -12,6 +12,8 @@ contract('Basic contract functionality', ([creator, alice]) => { await this.lockUpPool.initialize(); await this.lockUpPool.addLockUpPool(this.hunt.address, toBN(9999999999999)); + + this.SECONDS_IN_MONTH = +(await this.lockUpPool.SECONDS_IN_MONTH().valueOf()); }); it('balance of creator should have initial supply', async () => { @@ -109,7 +111,7 @@ contract('Basic contract functionality', ([creator, alice]) => { await this.hunt.approve(this.lockUpPool.address, 1000, { from: creator }); await this.lockUpPool.doLockUp(this.hunt.address, 1000, 3, { from: creator }); - await time.increase(86400 * 30 * 4); + await time.increase(this.SECONDS_IN_MONTH * 4); await this.lockUpPool.exit(this.hunt.address, 0, false, { from: creator }); @@ -134,50 +136,26 @@ contract('Basic contract functionality', ([creator, alice]) => { assert.equal((await this.hunt.balanceOf(alice)).valueOf(), 8700); assert.equal((await this.hunt.balanceOf(await this.lockUpPool.fundAddress().valueOf())).valueOf(), 300); // platform fee - const [ - durationInMonths, - unlockedAt, - amount, - effectiveAmount, - exitedAt, - penalty, - fee - ] = Object.values(await this.lockUpPool.getLockUp(this.hunt.address, alice, 0)); - assert.equal(durationInMonths, 3); - assert.equal(amount, 10000); - assert.equal(effectiveAmount, 10000); - assert.equal(penalty, 1000); - assert.equal(fee, 300); + const [, unlockedAt, , , exitedAt] = Object.values(await this.lockUpPool.getLockUp(this.hunt.address, alice, 0)); + assert.equal(unlockedAt > exitedAt, true); }); it('should not cut any fee on matured lockup', async () => { await this.hunt.approve(this.lockUpPool.address, 10000, { from: creator }); - await this.lockUpPool.doLockUp(this.hunt.address, 10000, 6, { from: creator }); - await time.increase(86400 * 30 * 4); + await this.lockUpPool.doLockUp(this.hunt.address, 10000, 3, { from: creator }); + await time.increase(this.SECONDS_IN_MONTH * 4); await this.lockUpPool.exit(this.hunt.address, 0, false, { from: creator }); assert.equal((await this.hunt.balanceOf(creator, { from: creator })).valueOf(), 10000); - const [ - durationInMonths, - unlockedAt, - amount, - effectiveAmount, - exitedAt, - penalty, - fee - ] = Object.values(await this.lockUpPool.getLockUp(this.hunt.address, creator, 0)); - assert.equal(durationInMonths, 6); - assert.equal(amount, 10000); - assert.equal(effectiveAmount, 20000); - assert.equal(penalty, 0); - assert.equal(fee, 0); + const [, unlockedAt, , , exitedAt] = Object.values(await this.lockUpPool.getLockUp(this.hunt.address, creator, 0)); + assert.equal(unlockedAt < exitedAt, true); }); it('should handle double-exits properly', async () => { await this.hunt.approve(this.lockUpPool.address, 10000, { from: creator }); await this.lockUpPool.doLockUp(this.hunt.address, 10000, 3, { from: creator }); - await time.increase(86400 * 30 * 4); + await time.increase(this.SECONDS_IN_MONTH * 4); await this.lockUpPool.exit(this.hunt.address, 0, false, { from: creator }); await expectRevert( diff --git a/test/LockUpPoolDetail.test.js b/test/LockUpPoolDetail.test.js index e256ced..d32793e 100644 --- a/test/LockUpPoolDetail.test.js +++ b/test/LockUpPoolDetail.test.js @@ -36,7 +36,7 @@ contract('LockUp and Exit', ([creator, alice, bob, carol]) => { await this.lockUpPool.doLockUp(this.hunt.address, toBN(1000), 12, { from: alice }); // duration boost: 4x // Total lockUp stats - const [, totalLockUp, effectiveTotalLockUp, , ,] = Object.values(await this.lockUpPool.tokenStats(this.hunt.address, { from: creator })); + const [, totalLockUp, effectiveTotalLockUp] = Object.values(await this.lockUpPool.tokenStats(this.hunt.address, { from: creator })); assert.equal(totalLockUp.valueOf(), toBN(2000)); assert.equal(effectiveTotalLockUp.valueOf(), toBN(5000)); @@ -44,22 +44,23 @@ contract('LockUp and Exit', ([creator, alice, bob, carol]) => { await this.lockUpPool.exit(this.hunt.address, 0, true, { from: alice }); // My lockUp stats - const [amount, effectiveAmount,,,] = Object.values(await this.lockUpPool.userLockUps(this.hunt.address, creator, { from: creator })); + const [amount, effectiveAmount] = Object.values(await this.lockUpPool.userLockUps(this.hunt.address, creator, { from: creator })); assert.equal(amount.valueOf(), toBN(1000)); assert.equal(effectiveAmount.valueOf(), toBN(1000)); - const [amount1, effectiveAmount1,,,] = Object.values(await this.lockUpPool.userLockUps(this.hunt.address, alice, { from: alice })); + const [amount1, effectiveAmount1] = Object.values(await this.lockUpPool.userLockUps(this.hunt.address, alice, { from: alice })); assert.equal(amount1.valueOf(), 0); assert.equal(effectiveAmount1.valueOf(), 0); // Total lockUp stats - const [, totalLockUp1, effectiveTotalLockUp1, totalPenalty, totalPlatformFee,] = Object.values(await this.lockUpPool.tokenStats(this.hunt.address, { from: creator })); - assert.equal(totalLockUp1.valueOf(), toBN(1000)); - assert.equal(effectiveTotalLockUp1.valueOf(), toBN(1000)); + const [, totalLockUp1, effectiveTotalLockUp1, , totalPenalty, accTotalLockUp] = Object.values(await this.lockUpPool.tokenStats(this.hunt.address)); + assert.equal(+totalLockUp1, toBN(1000)); + assert.equal(+effectiveTotalLockUp1, toBN(1000)); assert.equal((await this.hunt.balanceOf(await this.lockUpPool.fundAddress().valueOf())).valueOf(), toBN(30)); // 3% platform fee should go to the fund assert.equal((await this.hunt.balanceOf(alice)).valueOf(), toBN(870)); // 10% penalty + 3% platform fees are deducted - assert.equal(totalPenalty, toBN(100)); - assert.equal(totalPlatformFee, toBN(30)); + assert.equal(+totalPenalty, toBN(100)); + assert.equal(+accTotalLockUp, toBN(2000)); + // assert.equal(totalPlatformFee, toBN(30)); - not recorded }); it('penalty should be distributed to the participants', async () => { @@ -111,14 +112,13 @@ contract('LockUp and Exit', ([creator, alice, bob, carol]) => { await this.lockUpPool.exit(this.hunt.address, 1, true, { from: alice }); assert.equal((await this.lockUpPool.earnedBonus(this.hunt.address, { from: bob })).valueOf(), toBN(10)); - const [, totalLockUp, effectiveTotalLockUp, totalPenalty, totalPlatformFee, totalClaimed] = Object.values(await this.lockUpPool.tokenStats(this.hunt.address, { from: creator })); - assert.equal(totalLockUp.valueOf(), toBN(1000)); - assert.equal(effectiveTotalLockUp.valueOf(), toBN(1000)); - assert.equal(totalPenalty.valueOf(), toBN(210)); - assert.equal(totalPlatformFee.valueOf(), toBN(63)); - assert.equal(totalClaimed.valueOf(), toBN(100)); - assert.equal((await this.lockUpPool.totalClaimableBonus(this.hunt.address)).valueOf(), toBN(110)); - // but actually, only 100 is claimable because there was a point when the pool emptied out + const [, totalLockUp, effectiveTotalLockUp, , totalPenalty, accTotalLockUp] = Object.values(await this.lockUpPool.tokenStats(this.hunt.address, { from: creator })); + assert.equal(+totalLockUp, toBN(1000)); + assert.equal(+effectiveTotalLockUp, toBN(1000)); + assert.equal(+totalPenalty, toBN(210)); + assert.equal(+accTotalLockUp, toBN(3100)); + // assert.equal(totalPlatformFee.valueOf(), toBN(63)); - not recorded + // assert.equal(totalClaimed.valueOf(), toBN(100)); - not recorded }); it('lock-up comes later should not affect already earned bonus of former users', async () => { diff --git a/test/helpers/LogHelpers.js b/test/helpers/LogHelpers.js index 13b6838..75d2ea1 100644 --- a/test/helpers/LogHelpers.js +++ b/test/helpers/LogHelpers.js @@ -2,23 +2,29 @@ const { time } = require('@openzeppelin/test-helpers'); async function printTokenStats(lockUpPool, tokenAddress) { const [ - poolExists, + maxLockUpLimit, totalLockUp, effectiveTotalLockUp, - totalPenalty, - totalPlatformFee, - totalClaimed, accBonusPerShare, + totalPenalty, + accTotalLockUp, + accLockUpCount, + activeLockUpCount, + unlockedCount, + brokenCount ] = Object.values(await lockUpPool.tokenStats(tokenAddress)).map(v => v.valueOf().toString()); console.log("----------------- Token Stats -----------------\n", { - poolExists, + maxLockUpLimit, totalLockUp, effectiveTotalLockUp, - totalPenalty, - totalPlatformFee, - totalClaimed, accBonusPerShare, + totalPenalty, + accTotalLockUp, + accLockUpCount, + activeLockUpCount, + unlockedCount, + brokenCount }); } @@ -26,17 +32,20 @@ async function printUserLockUps(lockUpPool, tokenAddress, account) { const [ total, effectiveTotal, + accTotal, bonusClaimed, bonusDebt, lockedUpCount, - lockUps, + lockUps ] = Object.values(await lockUpPool.userLockUps(tokenAddress, account)).map(v => v.valueOf().toString()); console.log("----------------- User LockUp Stats -----------------\n", { total, effectiveTotal, + accTotal, bonusClaimed, bonusDebt, + lockedUpCount }); } From 61926eb8d24e0bd48b403d1c5524cffb78eb1216 Mon Sep 17 00:00:00 2001 From: Sebastian Kim Date: Fri, 20 Nov 2020 14:34:34 +0900 Subject: [PATCH 4/7] Update gas table --- README.md | 52 +++++++++++++++++++++++------------------------ truffle-config.js | 1 + 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index cedccc5..62f560d 100644 --- a/README.md +++ b/README.md @@ -34,60 +34,60 @@ A governance token distribution contract on top of LockUpPool. A maximum of 1.2M ·------------------------------------------------|---------------------------|--------------|----------------------------· | Solc version: 0.7.1+commit.f4a555be · Optimizer enabled: true · Runs: 1500 · Block limit: 6718946 gas │ ·················································|···························|··············|····························· -| Methods · 27 gwei/gas · 472.47 usd/eth │ +| Methods · 25 gwei/gas · 484.30 usd/eth │ ························|························|·············|·············|··············|··············|·············· | Contract · Method · Min · Max · Avg · # calls · usd (avg) │ ························|························|·············|·············|··············|··············|·············· -| ERC20Token · addMinter · 72827 · 75612 · 73116 · 30 · 0.93 │ +| ERC20Token · addMinter · 72827 · 75612 · 73098 · 32 · 0.89 │ ························|························|·············|·············|··············|··············|·············· -| ERC20Token · approve · 29070 · 46897 · 43960 · 127 · 0.56 │ +| ERC20Token · approve · 29070 · 46897 · 43962 · 129 · 0.53 │ ························|························|·············|·············|··············|··············|·············· -| ERC20Token · initialize · 324430 · 369343 · 356923 · 98 · 4.55 │ +| ERC20Token · initialize · 324430 · 369343 · 356528 · 102 · 4.32 │ ························|························|·············|·············|··············|··············|·············· -| ERC20Token · mint · - · - · 52871 · 49 · 0.67 │ +| ERC20Token · mint · - · - · 52871 · 49 · 0.64 │ ························|························|·············|·············|··············|··············|·············· -| ERC20Token · transfer · 37081 · 52141 · 51421 · 21 · 0.66 │ +| ERC20Token · transfer · 37081 · 52141 · 51421 · 21 · 0.62 │ ························|························|·············|·············|··············|··············|·············· -| LockUpPool · addLockUpPool · 71227 · 86311 · 84685 · 37 · 1.08 │ +| LockUpPool · addLockUpPool · 71215 · 86311 · 84684 · 37 · 1.03 │ ························|························|·············|·············|··············|··············|·············· -| LockUpPool · claimBonus · 26660 · 126167 · 72998 · 3 · 0.93 │ +| LockUpPool · claimBonus · 26634 · 105197 · 64009 · 3 · 0.77 │ ························|························|·············|·············|··············|··············|·············· -| LockUpPool · doLockUp · 191797 · 356752 · 299921 · 46 · 3.83 │ +| LockUpPool · doLockUp · 185088 · 350039 · 297643 · 46 · 3.60 │ ························|························|·············|·············|··············|··············|·············· -| LockUpPool · exit · 69530 · 287168 · 191781 · 31 · 2.45 │ +| LockUpPool · exit · 58256 · 207065 · 134292 · 31 · 1.63 │ ························|························|·············|·············|··············|··············|·············· -| LockUpPool · initialize · - · - · 155573 · 31 · 1.98 │ +| LockUpPool · initialize · - · - · 116378 · 31 · 1.41 │ ························|························|·············|·············|··············|··············|·············· -| LockUpPool · setEmergencyMode · - · - · 43203 · 4 · 0.55 │ +| LockUpPool · setEmergencyMode · - · - · 28217 · 4 · 0.34 │ ························|························|·············|·············|··············|··············|·············· -| LockUpPool · updateMaxLimit · 28742 · 28814 · 28778 · 2 · 0.37 │ +| LockUpPool · updateMaxLimit · 28764 · 28836 · 28800 · 2 · 0.35 │ ························|························|·············|·············|··············|··············|·············· -| Migrations · setCompleted · - · - · 21204 · 5 · 0.27 │ +| Migrations · setCompleted · - · - · 21204 · 5 · 0.26 │ ························|························|·············|·············|··············|··············|·············· -| WRNRewardPool · addLockUpRewardPool · 100340 · 223565 · 133451 · 37 · 1.70 │ +| WRNRewardPool · addLockUpRewardPool · 101166 · 224459 · 121812 · 39 · 1.47 │ ························|························|·············|·············|··············|··············|·············· -| WRNRewardPool · claimWRN · 146764 · 202564 · 183964 · 6 · 2.35 │ +| WRNRewardPool · claimWRN · 146843 · 202655 · 184051 · 6 · 2.23 │ ························|························|·············|·············|··············|··············|·············· -| WRNRewardPool · doLockUp · 326314 · 414161 · 394392 · 28 · 5.03 │ +| WRNRewardPool · doLockUp · 304647 · 422522 · 390196 · 30 · 4.72 │ ························|························|·············|·············|··············|··············|·············· -| WRNRewardPool · exit · 194309 · 370528 · 305938 · 7 · 3.90 │ +| WRNRewardPool · exit · 159206 · 290450 · 245126 · 7 · 2.97 │ ························|························|·············|·············|··············|··············|·············· -| WRNRewardPool · initialize · 280112 · 280232 · 280156 · 27 · 3.57 │ +| WRNRewardPool · initialize · 241822 · 241954 · 241873 · 29 · 2.93 │ ························|························|·············|·············|··············|··············|·············· -| WRNRewardPool · setEmergencyMode · - · - · 43181 · 1 · 0.55 │ +| WRNRewardPool · setEmergencyMode · - · - · 28218 · 1 · 0.34 │ ························|························|·············|·············|··············|··············|·············· -| WRNRewardPool · updatePoolMultiplier · - · - · 222978 · 1 · 2.84 │ +| WRNRewardPool · updatePoolMultiplier · - · - · 223728 · 1 · 2.71 │ ························|························|·············|·············|··············|··············|·············· -| WRNRewardPoolV2Test · setVarAdded · - · - · 44291 · 1 · 0.57 │ +| WRNRewardPoolV2Test · setVarAdded · - · - · 44247 · 1 · 0.54 │ ························|························|·············|·············|··············|··············|·············· | Deployments · · % of limit · │ ·················································|·············|·············|··············|··············|·············· -| ERC20Token · - · - · 1926451 · 28.7 % · 24.58 │ +| ERC20Token · - · - · 1926451 · 28.7 % · 23.32 │ ·················································|·············|·············|··············|··············|·············· -| LockUpPool · - · - · 2025346 · 30.1 % · 25.84 │ +| LockUpPool · - · - · 1950515 · 29 % · 23.62 │ ·················································|·············|·············|··············|··············|·············· -| WRNRewardPool · - · - · 2747015 · 40.9 % · 35.04 │ +| WRNRewardPool · - · - · 2677676 · 39.9 % · 32.42 │ ·················································|·············|·············|··············|··············|·············· -| WRNRewardPoolV2Test · - · - · 2535788 · 37.7 % · 32.35 │ +| WRNRewardPoolV2Test · - · - · 2446820 · 36.4 % · 29.62 │ ·------------------------------------------------|-------------|-------------|--------------|--------------|-------------· ``` diff --git a/truffle-config.js b/truffle-config.js index 679dd7e..25d9e0b 100644 --- a/truffle-config.js +++ b/truffle-config.js @@ -51,6 +51,7 @@ module.exports = { reporterOptions : { currency: 'USD', coinmarketcap: '793664cd-7f8f-470f-867b-9de05f7d411d' + // gasPrice: 25 } }, api_keys: { From 89b35aaa22ca252d24993ee094d75fd9c43b19da Mon Sep 17 00:00:00 2001 From: Sebastian Kim Date: Fri, 20 Nov 2020 16:48:18 +0900 Subject: [PATCH 5/7] Update deploy settings --- .openzeppelin/goerli.json | 552 +++++++++++++++++++++++++ README.md | 10 +- contracts/LockUpPool.sol | 3 +- migrations/2_deploy_wrn_reward_pool.js | 19 +- package.json | 2 +- scripts/send-test-tokens.js | 10 +- truffle-config.js | 4 +- yarn.lock | 398 +++++++++--------- 8 files changed, 786 insertions(+), 212 deletions(-) diff --git a/.openzeppelin/goerli.json b/.openzeppelin/goerli.json index 54af282..bdb62f2 100644 --- a/.openzeppelin/goerli.json +++ b/.openzeppelin/goerli.json @@ -727,6 +727,558 @@ } } } + }, + "0236c37c970548175a40fe52721bc68415db2e347864d721ab9e1669526c9d6e": { + "address": "0x77013996BDa18773c11b9d75466f2e6cB0e84736", + "txHash": "0x48e6bb6e79483d5adc44374075e10fd365dd364947f4a6627176b23e0a9471b6", + "layout": { + "storage": [ + { + "contract": "Initializable", + "label": "initialized", + "type": "t_bool", + "src": "openzeppelin/Initializable.sol:21" + }, + { + "contract": "Initializable", + "label": "initializing", + "type": "t_bool", + "src": "openzeppelin/Initializable.sol:26" + }, + { + "contract": "Initializable", + "label": "______gap", + "type": "t_array(t_uint256)50_storage", + "src": "openzeppelin/Initializable.sol:61" + }, + { + "contract": "ContextUpgradeSafe", + "label": "__gap", + "type": "t_array(t_uint256)50_storage", + "src": "openzeppelin/GSN/Context.sol:39" + }, + { + "contract": "AccessControlUpgradeSafe", + "label": "_roles", + "type": "t_mapping(t_bytes32,t_struct(RoleData)2016_storage)", + "src": "openzeppelin/access/AccessControl.sol:59" + }, + { + "contract": "AccessControlUpgradeSafe", + "label": "__gap", + "type": "t_array(t_uint256)49_storage", + "src": "openzeppelin/access/AccessControl.sol:211" + }, + { + "contract": "ERC20UpgradeSafe", + "label": "_balances", + "type": "t_mapping(t_address,t_uint256)", + "src": "openzeppelin/token/ERC20/ERC20.sol:38" + }, + { + "contract": "ERC20UpgradeSafe", + "label": "_allowances", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))", + "src": "openzeppelin/token/ERC20/ERC20.sol:40" + }, + { + "contract": "ERC20UpgradeSafe", + "label": "_totalSupply", + "type": "t_uint256", + "src": "openzeppelin/token/ERC20/ERC20.sol:42" + }, + { + "contract": "ERC20UpgradeSafe", + "label": "_name", + "type": "t_string_storage", + "src": "openzeppelin/token/ERC20/ERC20.sol:44" + }, + { + "contract": "ERC20UpgradeSafe", + "label": "_symbol", + "type": "t_string_storage", + "src": "openzeppelin/token/ERC20/ERC20.sol:45" + }, + { + "contract": "ERC20UpgradeSafe", + "label": "_decimals", + "type": "t_uint8", + "src": "openzeppelin/token/ERC20/ERC20.sol:46" + }, + { + "contract": "ERC20UpgradeSafe", + "label": "__gap", + "type": "t_array(t_uint256)44_storage", + "src": "openzeppelin/token/ERC20/ERC20.sol:318" + }, + { + "contract": "ERC20BurnableUpgradeSafe", + "label": "__gap", + "type": "t_array(t_uint256)50_storage", + "src": "openzeppelin/token/ERC20/ERC20Burnable.sol:54" + }, + { + "contract": "PausableUpgradeSafe", + "label": "_paused", + "type": "t_bool", + "src": "openzeppelin/utils/Pausable.sol:27" + }, + { + "contract": "PausableUpgradeSafe", + "label": "__gap", + "type": "t_array(t_uint256)49_storage", + "src": "openzeppelin/utils/Pausable.sol:85" + }, + { + "contract": "ERC20PausableUpgradeSafe", + "label": "__gap", + "type": "t_array(t_uint256)50_storage", + "src": "openzeppelin/token/ERC20/ERC20Pausable.sol:40" + }, + { + "contract": "ERC20PresetMinterPauserUpgradeSafe", + "label": "__gap", + "type": "t_array(t_uint256)50_storage", + "src": "openzeppelin/presets/ERC20PresetMinterPauser.sol:102" + } + ], + "types": { + "t_array(t_uint256)50_storage": { + "label": "uint256[50]" + }, + "t_bool": { + "label": "bool" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]" + }, + "t_mapping(t_address,t_uint256)": { + "label": "mapping(address => uint256)" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "label": "mapping(address => mapping(address => uint256))" + }, + "t_uint256": { + "label": "uint256" + }, + "t_string_storage": { + "label": "string" + }, + "t_uint8": { + "label": "uint8" + }, + "t_array(t_uint256)44_storage": { + "label": "uint256[44]" + }, + "t_mapping(t_bytes32,t_struct(RoleData)2016_storage)": { + "label": "mapping(bytes32 => struct AccessControlUpgradeSafe.RoleData)" + } + } + } + }, + "7f87e8d8e036247b6dc020cef4305f51d9308711cc43a43ce7f2a507b3bc591b": { + "address": "0x02a24231c2Aff2AC295abF1AEB1395e0c1a80B63", + "txHash": "0xb188b6ac4ba6dcec34d662f87370ebf19a8730c232e1019a6a5d613588de1aa6", + "layout": { + "storage": [ + { + "contract": "Initializable", + "label": "initialized", + "type": "t_bool", + "src": "openzeppelin/Initializable.sol:21" + }, + { + "contract": "Initializable", + "label": "initializing", + "type": "t_bool", + "src": "openzeppelin/Initializable.sol:26" + }, + { + "contract": "Initializable", + "label": "______gap", + "type": "t_array(t_uint256)50_storage", + "src": "openzeppelin/Initializable.sol:61" + }, + { + "contract": "ContextUpgradeSafe", + "label": "__gap", + "type": "t_array(t_uint256)50_storage", + "src": "openzeppelin/GSN/Context.sol:39" + }, + { + "contract": "OwnableUpgradeSafe", + "label": "_owner", + "type": "t_address", + "src": "openzeppelin/access/Ownable.sol:19" + }, + { + "contract": "OwnableUpgradeSafe", + "label": "__gap", + "type": "t_array(t_uint256)49_storage", + "src": "openzeppelin/access/Ownable.sol:79" + }, + { + "contract": "LockUpPool", + "label": "PENALTY_RATE", + "type": "t_uint8", + "src": "LockUpPool.sol:16" + }, + { + "contract": "LockUpPool", + "label": "PLATFORM_FEE_RATE", + "type": "t_uint8", + "src": "LockUpPool.sol:17" + }, + { + "contract": "LockUpPool", + "label": "SECONDS_IN_MONTH", + "type": "t_uint24", + "src": "LockUpPool.sol:18" + }, + { + "contract": "LockUpPool", + "label": "emergencyMode", + "type": "t_bool", + "src": "LockUpPool.sol:20" + }, + { + "contract": "LockUpPool", + "label": "tokenStats", + "type": "t_mapping(t_address,t_struct(TokenStats)140_storage)", + "src": "LockUpPool.sol:54" + }, + { + "contract": "LockUpPool", + "label": "pools", + "type": "t_array(t_address)dyn_storage", + "src": "LockUpPool.sol:57" + }, + { + "contract": "LockUpPool", + "label": "userLockUps", + "type": "t_mapping(t_address,t_mapping(t_address,t_struct(UserLockUp)119_storage))", + "src": "LockUpPool.sol:60" + }, + { + "contract": "LockUpPool", + "label": "fundAddress", + "type": "t_address", + "src": "LockUpPool.sol:63" + }, + { + "contract": "LockUpPool", + "label": "______gap", + "type": "t_array(t_uint256)50_storage", + "src": "LockUpPool.sol:312" + }, + { + "contract": "WRNRewardPool", + "label": "WRNToken", + "type": "t_contract(ERC20PresetMinterPauserUpgradeSafe)2848", + "src": "WRNRewardPool.sol:12" + }, + { + "contract": "WRNRewardPool", + "label": "REWARD_START_BLOCK", + "type": "t_uint256", + "src": "WRNRewardPool.sol:15" + }, + { + "contract": "WRNRewardPool", + "label": "REWARD_END_BLOCK", + "type": "t_uint256", + "src": "WRNRewardPool.sol:16" + }, + { + "contract": "WRNRewardPool", + "label": "REWARD_EARLY_BONUS_END_BLOCK", + "type": "t_uint256", + "src": "WRNRewardPool.sol:17" + }, + { + "contract": "WRNRewardPool", + "label": "REWARD_PER_BLOCK", + "type": "t_uint256", + "src": "WRNRewardPool.sol:18" + }, + { + "contract": "WRNRewardPool", + "label": "REWARD_EARLY_BONUS_BOOST", + "type": "t_uint8", + "src": "WRNRewardPool.sol:19" + }, + { + "contract": "WRNRewardPool", + "label": "totalMultiplier", + "type": "t_uint16", + "src": "WRNRewardPool.sol:21" + }, + { + "contract": "WRNRewardPool", + "label": "wrnStats", + "type": "t_mapping(t_address,t_struct(WRNStats)1159_storage)", + "src": "WRNRewardPool.sol:34" + }, + { + "contract": "WRNRewardPool", + "label": "userWRNRewards", + "type": "t_mapping(t_address,t_mapping(t_address,t_struct(UserWRNReward)1164_storage))", + "src": "WRNRewardPool.sol:37" + }, + { + "contract": "WRNRewardPool", + "label": "______gap", + "type": "t_array(t_uint256)50_storage", + "src": "WRNRewardPool.sol:231" + } + ], + "types": { + "t_contract(ERC20PresetMinterPauserUpgradeSafe)2848": { + "label": "contract ERC20PresetMinterPauserUpgradeSafe" + }, + "t_uint256": { + "label": "uint256" + }, + "t_uint8": { + "label": "uint8" + }, + "t_uint16": { + "label": "uint16" + }, + "t_mapping(t_address,t_struct(WRNStats)1159_storage)": { + "label": "mapping(address => struct WRNRewardPool.WRNStats)" + }, + "t_mapping(t_address,t_mapping(t_address,t_struct(UserWRNReward)1164_storage))": { + "label": "mapping(address => mapping(address => struct WRNRewardPool.UserWRNReward))" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]" + }, + "t_uint24": { + "label": "uint24" + }, + "t_bool": { + "label": "bool" + }, + "t_mapping(t_address,t_struct(TokenStats)140_storage)": { + "label": "mapping(address => struct LockUpPool.TokenStats)" + }, + "t_array(t_address)dyn_storage": { + "label": "address[]" + }, + "t_mapping(t_address,t_mapping(t_address,t_struct(UserLockUp)119_storage))": { + "label": "mapping(address => mapping(address => struct LockUpPool.UserLockUp))" + }, + "t_address": { + "label": "address" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]" + } + } + } + }, + "3af5d63addacec60d8f3f837f6073d15d5bc1aaed2d7b9a959b43b3c3ccebf9f": { + "address": "0xBD7B355002163d555bE4482a392A501A3253EBD9", + "txHash": "0xd6358f9be09c86b12a6594a667c98de85eec8dce34ebf465a8c5af2691af905f", + "layout": { + "storage": [ + { + "contract": "Initializable", + "label": "initialized", + "type": "t_bool", + "src": "openzeppelin/Initializable.sol:21" + }, + { + "contract": "Initializable", + "label": "initializing", + "type": "t_bool", + "src": "openzeppelin/Initializable.sol:26" + }, + { + "contract": "Initializable", + "label": "______gap", + "type": "t_array(t_uint256)50_storage", + "src": "openzeppelin/Initializable.sol:61" + }, + { + "contract": "ContextUpgradeSafe", + "label": "__gap", + "type": "t_array(t_uint256)50_storage", + "src": "openzeppelin/GSN/Context.sol:39" + }, + { + "contract": "OwnableUpgradeSafe", + "label": "_owner", + "type": "t_address", + "src": "openzeppelin/access/Ownable.sol:19" + }, + { + "contract": "OwnableUpgradeSafe", + "label": "__gap", + "type": "t_array(t_uint256)49_storage", + "src": "openzeppelin/access/Ownable.sol:79" + }, + { + "contract": "LockUpPool", + "label": "PENALTY_RATE", + "type": "t_uint8", + "src": "LockUpPool.sol:16" + }, + { + "contract": "LockUpPool", + "label": "PLATFORM_FEE_RATE", + "type": "t_uint8", + "src": "LockUpPool.sol:17" + }, + { + "contract": "LockUpPool", + "label": "SECONDS_IN_MONTH", + "type": "t_uint24", + "src": "LockUpPool.sol:18" + }, + { + "contract": "LockUpPool", + "label": "emergencyMode", + "type": "t_bool", + "src": "LockUpPool.sol:20" + }, + { + "contract": "LockUpPool", + "label": "tokenStats", + "type": "t_mapping(t_address,t_struct(TokenStats)140_storage)", + "src": "LockUpPool.sol:54" + }, + { + "contract": "LockUpPool", + "label": "pools", + "type": "t_array(t_address)dyn_storage", + "src": "LockUpPool.sol:57" + }, + { + "contract": "LockUpPool", + "label": "userLockUps", + "type": "t_mapping(t_address,t_mapping(t_address,t_struct(UserLockUp)119_storage))", + "src": "LockUpPool.sol:60" + }, + { + "contract": "LockUpPool", + "label": "fundAddress", + "type": "t_address", + "src": "LockUpPool.sol:63" + }, + { + "contract": "LockUpPool", + "label": "______gap", + "type": "t_array(t_uint256)50_storage", + "src": "LockUpPool.sol:313" + }, + { + "contract": "WRNRewardPool", + "label": "WRNToken", + "type": "t_contract(ERC20PresetMinterPauserUpgradeSafe)2848", + "src": "WRNRewardPool.sol:12" + }, + { + "contract": "WRNRewardPool", + "label": "REWARD_START_BLOCK", + "type": "t_uint256", + "src": "WRNRewardPool.sol:15" + }, + { + "contract": "WRNRewardPool", + "label": "REWARD_END_BLOCK", + "type": "t_uint256", + "src": "WRNRewardPool.sol:16" + }, + { + "contract": "WRNRewardPool", + "label": "REWARD_EARLY_BONUS_END_BLOCK", + "type": "t_uint256", + "src": "WRNRewardPool.sol:17" + }, + { + "contract": "WRNRewardPool", + "label": "REWARD_PER_BLOCK", + "type": "t_uint256", + "src": "WRNRewardPool.sol:18" + }, + { + "contract": "WRNRewardPool", + "label": "REWARD_EARLY_BONUS_BOOST", + "type": "t_uint8", + "src": "WRNRewardPool.sol:19" + }, + { + "contract": "WRNRewardPool", + "label": "totalMultiplier", + "type": "t_uint16", + "src": "WRNRewardPool.sol:21" + }, + { + "contract": "WRNRewardPool", + "label": "wrnStats", + "type": "t_mapping(t_address,t_struct(WRNStats)1159_storage)", + "src": "WRNRewardPool.sol:34" + }, + { + "contract": "WRNRewardPool", + "label": "userWRNRewards", + "type": "t_mapping(t_address,t_mapping(t_address,t_struct(UserWRNReward)1164_storage))", + "src": "WRNRewardPool.sol:37" + }, + { + "contract": "WRNRewardPool", + "label": "______gap", + "type": "t_array(t_uint256)50_storage", + "src": "WRNRewardPool.sol:231" + } + ], + "types": { + "t_contract(ERC20PresetMinterPauserUpgradeSafe)2848": { + "label": "contract ERC20PresetMinterPauserUpgradeSafe" + }, + "t_uint256": { + "label": "uint256" + }, + "t_uint8": { + "label": "uint8" + }, + "t_uint16": { + "label": "uint16" + }, + "t_mapping(t_address,t_struct(WRNStats)1159_storage)": { + "label": "mapping(address => struct WRNRewardPool.WRNStats)" + }, + "t_mapping(t_address,t_mapping(t_address,t_struct(UserWRNReward)1164_storage))": { + "label": "mapping(address => mapping(address => struct WRNRewardPool.UserWRNReward))" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]" + }, + "t_uint24": { + "label": "uint24" + }, + "t_bool": { + "label": "bool" + }, + "t_mapping(t_address,t_struct(TokenStats)140_storage)": { + "label": "mapping(address => struct LockUpPool.TokenStats)" + }, + "t_array(t_address)dyn_storage": { + "label": "address[]" + }, + "t_mapping(t_address,t_mapping(t_address,t_struct(UserLockUp)119_storage))": { + "label": "mapping(address => mapping(address => struct LockUpPool.UserLockUp))" + }, + "t_address": { + "label": "address" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]" + } + } + } } }, "admin": { diff --git a/README.md b/README.md index 62f560d..22e722f 100644 --- a/README.md +++ b/README.md @@ -22,12 +22,12 @@ A governance token distribution contract on top of LockUpPool. A maximum of 1.2M ## Görli (goerli) Testnet - ETH faucet (to pay gas): https://faucet.goerli.mudit.blog/ -- Contract: 0xD5B9A9dB6E11E216e08bF10B0C0e53478315E8C3 +- Lock-up contract: 0x8f62599Ce9E93Cda072EA4F4E86dbaBF3CCC2bC9 - Test tokens - - WRN: 0x64B45af8ED1ABA874144802B34e99262E444202f - - HUNT: 0x3cCc84296b4dDf99d628e1472F697c4649A9962F - - WETH: 0x0370789664eCBc83a9a44766c2384b9d5A638Dfb - - WBTC: 0xF0aa78e4Ea6C717891085879Bd78Fd87a98D8572 + - WRN: 0xdAecEce4b065595907F04b8a9C96A9B7929Ee626 + - HUNT: 0xD409b07cC381c3D831F7fD71C4141c86DdC2a5c6 + - WETH: 0x608f8CeB3Af57Dd3b56b480B51dcfd7E7096acA3 + - WBTC: 0x48A32932F3BD2Fd7Bb31c97570290dE9d1e8827C ## Gas consumption ``` diff --git a/contracts/LockUpPool.sol b/contracts/LockUpPool.sol index 26cd4f9..9c92e7a 100644 --- a/contracts/LockUpPool.sol +++ b/contracts/LockUpPool.sol @@ -93,7 +93,8 @@ contract LockUpPool is Initializable, OwnableUpgradeSafe { SECONDS_IN_MONTH = 3600; // For TEST: 1 month = 1 hour // SECONDS_IN_MONTH = 2592000; // TODO: Uncomment it on production - fundAddress = address(0x82CA6d313BffE56E9096b16633dfD414148D66b1); + // fundAddress = address(0x82CA6d313BffE56E9096b16633dfD414148D66b1); // TODO: Uncomment it on production + fundAddress = address(0xFC7041F1d7346e24D0De183a98CC08Eb4DF482B1); // Testnet } modifier _checkPoolExists(address tokenAddress) { diff --git a/migrations/2_deploy_wrn_reward_pool.js b/migrations/2_deploy_wrn_reward_pool.js index 716180e..d3ae934 100644 --- a/migrations/2_deploy_wrn_reward_pool.js +++ b/migrations/2_deploy_wrn_reward_pool.js @@ -12,23 +12,24 @@ module.exports = async function (deployer, network, [creator]) { // NOTE: Use of `unsafeAllowCustomTypes` as UpgradesPlugins currently do not support validating custom types (enums or structs) // REF: https://docs.openzeppelin.com/upgrades-plugins/1.x/faq#what-does-it-mean-for-an-implementation-to-be-compatible const wrnToken = await deployProxy(ERC20Token, ['TEST WARREN', 'WRN', 18, toBN(0)], { deployer, unsafeAllowCustomTypes: true }); - const hunt = await deployProxy(ERC20Token, ['TEST HUNT Token', 'HUNT', 18, toBN(1000000)], { deployer, unsafeAllowCustomTypes: true }); - const weth = await deployProxy(ERC20Token, ['TEST Wrapped ETH', 'WETH', 18, toBN(10000)], { deployer, unsafeAllowCustomTypes: true }); - const wbtc = await deployProxy(ERC20Token, ['TEST Wrapped BTC', 'WBTC', 8, toBN(1000, 8)], { deployer, unsafeAllowCustomTypes: true }); + const hunt = await deployProxy(ERC20Token, ['TEST HUNT Token', 'HUNT', 18, toBN(500000 * 200)], { deployer, unsafeAllowCustomTypes: true }); + const weth = await deployProxy(ERC20Token, ['TEST Wrapped ETH', 'WETH', 18, toBN(40 * 200)], { deployer, unsafeAllowCustomTypes: true }); + const wbtc = await deployProxy(ERC20Token, ['TEST Wrapped BTC', 'WBTC', 8, toBN(1 * 200, 8)], { deployer, unsafeAllowCustomTypes: true }); const block = await web3.eth.getBlock("latest"); - const wrnRewardPool = await deployProxy(WRNRewardPool, [wrnToken.address, block.number, 8800000, 500000], { deployer, unsafeAllowCustomTypes: true }); + // Reward period will be: 14 days, bonus period: 7 days + const wrnRewardPool = await deployProxy(WRNRewardPool, [wrnToken.address, block.number, 100000, 50000], { deployer, unsafeAllowCustomTypes: true }); await wrnToken.addMinter(wrnRewardPool.address, { from: creator }); - await wrnRewardPool.addLockUpRewardPool(hunt.address, 2, toBN(10000), false); - await wrnRewardPool.addLockUpRewardPool(weth.address, 1, toBN(10000), false); - await wrnRewardPool.addLockUpRewardPool(wbtc.address, 1, toBN(10000, 8), false); + await wrnRewardPool.addLockUpRewardPool(hunt.address, 2, toBN(100000000), false); + await wrnRewardPool.addLockUpRewardPool(weth.address, 1, toBN(1000000), false); + await wrnRewardPool.addLockUpRewardPool(wbtc.address, 1, toBN(100000, 8), false); console.log(`- Lock-up Contract: ${wrnRewardPool.address}`); console.log('- Test tokens'); console.log(` - WRN: ${wrnToken.address}\n - HUNT: ${hunt.address}\n - WETH: ${weth.address}\n - WBTC: ${wbtc.address}`); - console.log(`Owner: ${await wrnRewardPool.owner()} / Dev: ${await wrnRewardPool.devAddress()}`); + console.log(`Owner: ${await wrnRewardPool.owner()} / Fund: ${await wrnRewardPool.fundAddress()}`); console.log(`Sum of reward pool multiplers: ${await wrnRewardPool.totalMultiplier()}`); console.log(`Owner HUNT balance: ${await hunt.balanceOf(creator)}`); } else if (network === 'mainnet') { @@ -51,7 +52,7 @@ module.exports = async function (deployer, network, [creator]) { console.log(`-> Lock-up Contract: ${wrnRewardPool.address}`); console.log(`-> WRN: ${wrnToken.address}`); - console.log(`- Owner: ${await wrnRewardPool.owner()} / Dev: ${await wrnRewardPool.devAddress()}`); + console.log(`- Owner: ${await wrnRewardPool.owner()} / Fund: ${await wrnRewardPool.fundAddress()}`); console.log(`- Sum of reward pool multiplers: ${await wrnRewardPool.totalMultiplier()}`); } } diff --git a/package.json b/package.json index 48b89d8..947305a 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "devDependencies": { "@openzeppelin/contracts-ethereum-package": "^3.0.0", "@openzeppelin/test-helpers": "^0.5.6", - "@openzeppelin/truffle-upgrades": "^1.2.1", + "@openzeppelin/truffle-upgrades": "^1.2.5", "@truffle/hdwallet-provider": "^1.1.1", "dotenv": "^8.2.0", "eth-gas-reporter": "^0.2.17", diff --git a/scripts/send-test-tokens.js b/scripts/send-test-tokens.js index 5797595..01dbd1a 100644 --- a/scripts/send-test-tokens.js +++ b/scripts/send-test-tokens.js @@ -13,9 +13,9 @@ const infuraProvider = (network) => { const web3 = new Web3(infuraProvider('goerli')); const tokenAddresses = { - HUNT: '0x853bCea4C256873d848072a207cc07dEf695faC8', - WETH: '0xf4540e848448AF2357D5ba6210b88CcD8e7B1b4E', - WBTC: '0xc0f4FC816968283D52a096d951094a9C1c037B13' + HUNT: '0xD409b07cC381c3D831F7fD71C4141c86DdC2a5c6', + WETH: '0x608f8CeB3Af57Dd3b56b480B51dcfd7E7096acA3', + WBTC: '0x48A32932F3BD2Fd7Bb31c97570290dE9d1e8827C' } async function sendETH(from, to, amount) { @@ -69,9 +69,9 @@ async function sendAll(to) { await sendETH(owner, to, 1); for (let token in tokenAddresses) { - let amount = 10000; + let amount = 500000; if(token === 'WETH') { - amount = 10; + amount = 40; } else if (token === 'WBTC') { amount = 1; } diff --git a/truffle-config.js b/truffle-config.js index 25d9e0b..a50916b 100644 --- a/truffle-config.js +++ b/truffle-config.js @@ -25,13 +25,13 @@ module.exports = { goerli: { provider: infuraProvider('goerli'), network_id: '5', - gas: 5000000, + gas: 7000000, gasPrice: 5000000000 // 5 gwei }, mainnet: { provider: infuraProvider('mainnet'), network_id: '1', - gas: 5000000, + gas: 7000000, gasPrice: 31000000000 // 31 gwei }, }, diff --git a/yarn.lock b/yarn.lock index 0e68c72..241d0a5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3,11 +3,11 @@ "@babel/helper-module-imports@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.1.tgz#1644c01591a15a2f084dd6d092d9430eb1d1216c" - integrity sha512-ZeC1TlMSvikvJNy1v/wPIazCu3NdOwgYZLIkmIyAsGhqkNpiDoQQRmaCK8YP4Pq3GPTLPV9WXaPCJKvx06JxKA== + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz#1bfc0229f794988f76ed0a4d4e90860850b54dfb" + integrity sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA== dependencies: - "@babel/types" "^7.12.1" + "@babel/types" "^7.12.5" "@babel/helper-plugin-utils@^7.10.4": version "7.10.4" @@ -30,16 +30,16 @@ semver "^5.5.1" "@babel/runtime@^7.5.5": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.1.tgz#b4116a6b6711d010b2dad3b7b6e43bf1b9954740" - integrity sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA== + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" + integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== dependencies: regenerator-runtime "^0.13.4" -"@babel/types@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.1.tgz#e109d9ab99a8de735be287ee3d6a9947a190c4ae" - integrity sha512-BzSY3NJBKM4kyatSOWh3D/JJ2O3CVzBybHWxtgxnggaxEuaSTTDqeiSb/xk9lrkw2Tbqyivw5ZU4rT+EfznQsA== +"@babel/types@^7.12.5": + version "7.12.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.6.tgz#ae0e55ef1cce1fbc881cd26f8234eb3e657edc96" + integrity sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA== dependencies: "@babel/helper-validator-identifier" "^7.10.4" lodash "^4.17.19" @@ -61,9 +61,9 @@ "@ethersproject/strings" ">=5.0.0-beta.130" "@ethersproject/abi@^5.0.0-beta.146": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.7.tgz#79e52452bd3ca2956d0e1c964207a58ad1a0ee7b" - integrity sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw== + version "5.0.8" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.8.tgz#b79e8b90932f0ce4b5796f21ec854e4fac4e6f7a" + integrity sha512-QiWzNybzepEmFfwxqEOoUm9i8G5fBuxMiiMcyUwXqywKtktbhNHpUbfOapMkEvPB8VgefzaUf1vHDSqC2Dc8Eg== dependencies: "@ethersproject/address" "^5.0.4" "@ethersproject/bignumber" "^5.0.7" @@ -76,9 +76,9 @@ "@ethersproject/strings" "^5.0.4" "@ethersproject/abstract-provider@^5.0.4": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.0.5.tgz#797a32a8707830af1ad8f833e9c228994d5572b9" - integrity sha512-i/CjElAkzV7vQBAeoz+IpjGfcFYEP9eD7j3fzZ0fzTq03DO7PPnR+xkEZ1IoDXGwDS+55aLM1xvLDwB/Lx6IOQ== + version "5.0.6" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.0.6.tgz#fd379b4c2dbb316841dd4f581a73b95d7f399a13" + integrity sha512-3GJjD+wM8J160XFiTMkDu1UFV9uA1OdbMUI0aYy1CFepxYGSh9vY12bsbiYiTJLXQ86usvSBK6OA9U7IqmKZVw== dependencies: "@ethersproject/bignumber" "^5.0.7" "@ethersproject/bytes" "^5.0.4" @@ -89,9 +89,9 @@ "@ethersproject/web" "^5.0.6" "@ethersproject/abstract-signer@^5.0.6": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.0.7.tgz#cdbd3bd479edf77c71b7f6a6156b0275b1176ded" - integrity sha512-8W8gy/QutEL60EoMEpvxZ8MFAEWs/JvH5nmZ6xeLXoZvmBCasGmxqHdYjo2cxg0nevkPkq9SeenSsBBZSCx+SQ== + version "5.0.8" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.0.8.tgz#16d8107ea718ad7a9b5925bd870aa40c05fbfba3" + integrity sha512-Q5ZJtxs5txKBfTbdXRI4n6Nn4EJlKg3zA22S4Eg+P3hIZ+cXoLoK9CnA1GeKMRHJiDBqECnWqeQl+yyGR7D+jg== dependencies: "@ethersproject/abstract-provider" "^5.0.4" "@ethersproject/bignumber" "^5.0.7" @@ -100,51 +100,50 @@ "@ethersproject/properties" "^5.0.3" "@ethersproject/address@>=5.0.0-beta.128", "@ethersproject/address@^5.0.4", "@ethersproject/address@^5.0.5": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.5.tgz#2caa65f6b7125015395b1b54c985ee0b27059cc7" - integrity sha512-DpkQ6rwk9jTefrRsJzEm6nhRiJd9pvhn1xN0rw5N/jswXG5r7BLk/GVA0mMAVWAsYfvi2xSc5L41FMox43RYEA== + version "5.0.7" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.7.tgz#ee7fd7d3b3a400dec6035c7b3f0b7e4652207308" + integrity sha512-+63DiYG+2og6rFNvQmLlLw8i5LtyT65n+jtHd06Ic81rLHc+JUKRpeZFhBa+gqh9f+P8V0xtKR5NI/EHXOfgSw== dependencies: - "@ethersproject/bignumber" "^5.0.7" + "@ethersproject/bignumber" "^5.0.10" "@ethersproject/bytes" "^5.0.4" "@ethersproject/keccak256" "^5.0.3" "@ethersproject/logger" "^5.0.5" "@ethersproject/rlp" "^5.0.3" - bn.js "^4.4.0" "@ethersproject/base64@^5.0.3": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.0.4.tgz#b0d8fdbf3dda977cf546dcd35725a7b1d5256caa" - integrity sha512-4KRykQ7BQMeOXfvio1YITwHjxwBzh92UoXIdzxDE1p53CK28bbHPdsPNYo0wl0El7lJAMpT2SOdL0hhbWRnyIA== + version "5.0.5" + resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.0.5.tgz#1c4873b075e40154c319ee0414aab105415e4072" + integrity sha512-4GJ9InM+zDDiiejPG/TrNGXVgD8D4BClEfJ3w45+ufyFA7QDT3gkAy+SdmmQCGAEBB+79MmXMLFq7TNtDM2DaA== dependencies: "@ethersproject/bytes" "^5.0.4" -"@ethersproject/bignumber@>=5.0.0-beta.130", "@ethersproject/bignumber@^5.0.7", "@ethersproject/bignumber@^5.0.8": - version "5.0.8" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.8.tgz#cee33bd8eb0266176def0d371b45274b1d2c4ec0" - integrity sha512-KXFVAFKS1jdTXYN8BE5Oj+ZfPMh28iRdFeNGBVT6cUFdtiPVqeXqc0ggvBqA3A1VoFFGgM7oAeaagA393aORHA== +"@ethersproject/bignumber@>=5.0.0-beta.130", "@ethersproject/bignumber@^5.0.10", "@ethersproject/bignumber@^5.0.7", "@ethersproject/bignumber@^5.0.8": + version "5.0.10" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.10.tgz#aee93d18f13b4976aba399888812804419ba2d5f" + integrity sha512-1b3bMe+PCjx6xI5IINzaWtNZEKtwq2guVrhuwRqQmHEsAgKDK+UMckXYsu0CwMwRsQoeq+sNuCWd64pCxkBqMw== dependencies: "@ethersproject/bytes" "^5.0.4" "@ethersproject/logger" "^5.0.5" bn.js "^4.4.0" "@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.4": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.5.tgz#688b70000e550de0c97a151a21f15b87d7f97d7c" - integrity sha512-IEj9HpZB+ACS6cZ+QQMTqmu/cnUK2fYNE6ms/PVxjoBjoxc6HCraLpam1KuRvreMy0i523PLmjN8OYeikRdcUQ== + version "5.0.6" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.6.tgz#848f8c10d78213eb743831fba0704154d3f39d13" + integrity sha512-axEmVeVy5IS0Sg46fNk4mygMm96uGd/15b6zmMu53w0NpHmOC/GYfpqMBHYxavjFYN+LUL7vVwgpbIFYGO2QHA== dependencies: "@ethersproject/logger" "^5.0.5" "@ethersproject/constants@>=5.0.0-beta.128", "@ethersproject/constants@^5.0.4": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.5.tgz#0ed19b002e8404bdf6d135234dc86a7d9bcf9b71" - integrity sha512-foaQVmxp2+ik9FrLUCtVrLZCj4M3Ibgkqvh+Xw/vFRSerkjVSYePApaVE5essxhoSlF1U9oXfWY09QI2AXtgKA== + version "5.0.6" + resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.6.tgz#bc8ca82d2c0eb1869e5cce4fee473e9a9a0e858c" + integrity sha512-ioBMaUsVb2+C8UVAHUpfrrkNtFEcAYNaZSf79Lw7VhjFRY5f1ImWGqSZhJb4/wKxaw0RIYLW7ZriDgcx2YMwWA== dependencies: "@ethersproject/bignumber" "^5.0.7" "@ethersproject/hash@>=5.0.0-beta.128", "@ethersproject/hash@^5.0.4": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.0.6.tgz#2a2e8a1470685421217e9e86e9971ca636e609ce" - integrity sha512-Gvh57v6BWhwnud6l7tMfQm32PRQ2DYx2WaAAQmAxAfYvmzUkpQCBstnGeNMXIL8/2wdkvcB2u+WZRWaZtsFuUQ== + version "5.0.7" + resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.0.7.tgz#e4ede972575d9aadffeab15070e9ffdf2f72d7e5" + integrity sha512-vYuRJRTAGHcYqQFAxxCgDpJtJv4aGC5TQm5NDZat/55BeLGLmH90ftJG1ldv7MhzGRxBPJtpqSHzJDizB6VKoA== dependencies: "@ethersproject/abstract-signer" "^5.0.6" "@ethersproject/address" "^5.0.5" @@ -156,44 +155,44 @@ "@ethersproject/strings" "^5.0.4" "@ethersproject/keccak256@>=5.0.0-beta.127", "@ethersproject/keccak256@^5.0.3": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.4.tgz#36ca0a7d1ae2a272da5654cb886776d0c680ef3a" - integrity sha512-GNpiOUm9PGUxFNqOxYKDQBM0u68bG9XC9iOulEQ8I0tOx/4qUpgVzvgXL6ugxr0RY554Gz/NQsVqknqPzUcxpQ== + version "5.0.5" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.5.tgz#414752fbdf9a2baa2634f4ed22f555bf5acbf536" + integrity sha512-9hXXp113jW5yPf27krofmnZ26u5SXsmuvrMTUuXyVdIDIJDLGorVyB2bBiWwENVok92E4WDnfAZHG+A+E6TCMQ== dependencies: "@ethersproject/bytes" "^5.0.4" js-sha3 "0.5.7" "@ethersproject/logger@>=5.0.0-beta.129", "@ethersproject/logger@^5.0.5": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.6.tgz#faa484203e86e08be9e07fef826afeef7183fe88" - integrity sha512-FrX0Vnb3JZ1md/7GIZfmJ06XOAA8r3q9Uqt9O5orr4ZiksnbpXKlyDzQtlZ5Yv18RS8CAUbiKH9vwidJg1BPmQ== + version "5.0.7" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.7.tgz#35c226ec6702ff1d6c4dcedd5121e54665f56e44" + integrity sha512-1wl+kDTPdDptpQdrkTmImubygUf0mVeo0I/p8d21qdzT16h/GnoJWt7q6Kt0xvTfcI7Jv4kryskxI2xV++w5Hg== "@ethersproject/networks@^5.0.3": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.0.4.tgz#6d320a5e15a0cda804f5da88be0ba846156f6eec" - integrity sha512-/wHDTRms5mpJ09BoDrbNdFWINzONe05wZRgohCXvEv39rrH/Gd/yAnct8wC0RsW3tmFOgjgQxuBvypIxuUynTw== + version "5.0.5" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.0.5.tgz#bd33013bc62b48bb4b8ce45ad3b05a602cb7eba2" + integrity sha512-DEcGEoRPtpbM+no9JmpwdCVVQELqYhP42BKArLsqps6nIEqOInWnjfpXfEss+nTrBp3zDrL4KNfOe7mS96C/mQ== dependencies: "@ethersproject/logger" "^5.0.5" "@ethersproject/properties@>=5.0.0-beta.131", "@ethersproject/properties@^5.0.3", "@ethersproject/properties@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.4.tgz#a67a1f5a52c30850b5062c861631e73d131f666e" - integrity sha512-UdyX3GqBxFt15B0uSESdDNmhvEbK3ACdDXl2soshoPcneXuTswHDeA0LoPlnaZzhbgk4p6jqb4GMms5C26Qu6A== + version "5.0.5" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.5.tgz#fb28b8dab39e876b9ca49b9b46b9f7bd95e2e469" + integrity sha512-2HwajwTUwlrOsiLVyyxiS4oP0a4xBNi1i90/kDJESmtlDmf2DkrY6qjBssa9YnWoEH34N/ZpLFVndimIrlo8kg== dependencies: "@ethersproject/logger" "^5.0.5" "@ethersproject/rlp@^5.0.3": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.4.tgz#0090a0271e84ea803016a112a79f5cfd80271a77" - integrity sha512-5qrrZad7VTjofxSsm7Zg/7Dr4ZOln4S2CqiDdOuTv6MBKnXj0CiBojXyuDy52M8O3wxH0CyE924hXWTDV1PQWQ== + version "5.0.5" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.5.tgz#9670e0ad0cba701593e3b0b2ab5e7404486979fa" + integrity sha512-RAUhk5+VH2UquTawgf7eK1i4Qbbzt0Ky6M27Q9JniRx0SBqmTkbKx/iXRZN/0x9vqQJhT596Z3vVevhqSa+GPQ== dependencies: "@ethersproject/bytes" "^5.0.4" "@ethersproject/logger" "^5.0.5" "@ethersproject/signing-key@^5.0.4": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.0.5.tgz#acfd06fc05a14180df7e027688bbd23fc4baf782" - integrity sha512-Z1wY7JC1HVO4CvQWY2TyTTuAr8xK3bJijZw1a9G92JEmKdv1j255R/0YLBBcFTl2J65LUjtXynNJ2GbArPGi5g== + version "5.0.6" + resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.0.6.tgz#78550155cf84fa78bde2ac1f723182f80c4c8cb3" + integrity sha512-KjyePQsh+L6BwmPWD5JoXCrRGjNfYSD5YeXQhy6YWQeMAfG0+WMG7U2SKzl+DWM+8/Ymat3s6o3U2GLXhGrcMg== dependencies: "@ethersproject/bytes" "^5.0.4" "@ethersproject/logger" "^5.0.5" @@ -201,18 +200,18 @@ elliptic "6.5.3" "@ethersproject/strings@>=5.0.0-beta.130", "@ethersproject/strings@^5.0.4": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.5.tgz#ed7e99a282a02f40757691b04a24cd83f3752195" - integrity sha512-JED6WaIV00xM/gvj8vSnd+0VWtDYdidTmavFRCTQakqfz+4tDo6Jz5LHgG+dd45h7ah7ykCHW0C7ZXWEDROCXQ== + version "5.0.6" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.6.tgz#722295012a052d68a42418404213b190a34c453b" + integrity sha512-eJf0TKk/X2MvR3OSaOsS4XhKkWTi4p7YrZp2P1DaiTP+xsxizMYI1Ds5VUB4DH4RIseUe4Sbf6eN2dfG+fhW2w== dependencies: "@ethersproject/bytes" "^5.0.4" "@ethersproject/constants" "^5.0.4" "@ethersproject/logger" "^5.0.5" "@ethersproject/transactions@^5.0.0-beta.135", "@ethersproject/transactions@^5.0.5": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.0.6.tgz#b8b27938be6e9ed671dbdd35fe98af8b14d0df7c" - integrity sha512-htsFhOD+NMBxx676A8ehSuwVV49iqpSB+CkjPZ02tpNew0K6p8g0CZ46Z1ZP946gIHAU80xQ0NACHYrjIUaCFA== + version "5.0.7" + resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.0.7.tgz#76260ab2df7de406371963ab7df1d50d1ca9139e" + integrity sha512-U7dyBMQ73lHUoAnp3fdcfhgvJwcow88b0/q7Fl6Id21/Ll7Dxe7qrWjR6pH6XTKV+h2a74o/pJS7CxNiwahaHw== dependencies: "@ethersproject/address" "^5.0.4" "@ethersproject/bignumber" "^5.0.7" @@ -225,9 +224,9 @@ "@ethersproject/signing-key" "^5.0.4" "@ethersproject/web@^5.0.6": - version "5.0.9" - resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.0.9.tgz#b08f8295f4bfd4777c8723fe9572f5453b9f03cb" - integrity sha512-//QNlv1MSkOII1hv3+HQwWoiVFS+BMVGI0KYeUww4cyrEktnx1QIez5bTSab9s9fWTFaWKNmQNBwMbxAqPuYDw== + version "5.0.10" + resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.0.10.tgz#ed4dc04ad9e81a68d44fc67afb38f1ed0578a647" + integrity sha512-j49TbzUJBggILUuZahNXG59ugktjfCJyJfNhmC068DwIG0k+ygYK2BV1CWP3uuh7H2DHZ6LMLC+IsWWKb8MDlA== dependencies: "@ethersproject/base64" "^5.0.3" "@ethersproject/bytes" "^5.0.4" @@ -264,19 +263,19 @@ web3 "^1.2.5" web3-utils "^1.2.5" -"@openzeppelin/truffle-upgrades@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@openzeppelin/truffle-upgrades/-/truffle-upgrades-1.2.1.tgz#e10c142bf90389e1317001acac551a9bb78f869f" - integrity sha512-9Ykd/SZRANeOCervP4a4z0Ntm2i6yJNLDSYJ3b0CRgH10F5LWhOdh7MXF5bkBJjMrMgJoEGkz0OwHlNdptJRoA== +"@openzeppelin/truffle-upgrades@^1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@openzeppelin/truffle-upgrades/-/truffle-upgrades-1.2.5.tgz#d0c9ea635d0f32eb57d38832e5050f0dd9eb52d9" + integrity sha512-gBMreQdjnMWkdczzi3XC/+HolCdF67TxoR9TKKtBuPjy+AXPJ+nxP9eYdOKtISQsi10bPj5AghiGYc2D7CfdlA== dependencies: "@openzeppelin/upgrades-core" "^1.2.0" "@truffle/contract" "^4.2.12" solidity-ast "^0.4.4" "@openzeppelin/upgrades-core@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/upgrades-core/-/upgrades-core-1.2.0.tgz#82ac78b010f0a59deb5ad5b1b4fac4fd2fecb265" - integrity sha512-qdFnvF8aYNu1jrM374EIQYsU8DFPj5o/ELqyzLZifbzFnNLiVJeObSplYBpfsDmj6Wz9apc8AT7/C+5howjfdw== + version "1.3.1" + resolved "https://registry.yarnpkg.com/@openzeppelin/upgrades-core/-/upgrades-core-1.3.1.tgz#b421bbc128eaf756c77671e69ced241494d39442" + integrity sha512-wdF++wE0K5GqhyM4fX732B99XqgGebbol28jhWgsG9cTFplxSzqqjxhgyMWRRik+KSPqBSIZZ4PF65knlQx0vg== dependencies: bn.js "^5.1.2" cbor "^5.0.2" @@ -329,9 +328,9 @@ integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== "@solidity-parser/parser@^0.8.0": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.8.1.tgz#1b606578af86b9ad10755409804a6ba83f9ce8a4" - integrity sha512-DF7H6T8I4lo2IZOE2NZwt3631T8j1gjpQLjmvY2xBNK50c4ltslR4XPKwT6RkeSd4+xCAK0GHC/k7sbRDBE4Yw== + version "0.8.2" + resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.8.2.tgz#a6a5e93ac8dca6884a99a532f133beba59b87b69" + integrity sha512-8LySx3qrNXPgB5JiULfG10O3V7QTxI/TLzSw5hFQhXWSkVxZBAv4rZQ0sYgLEbc8g3L2lmnujj1hKul38Eu5NQ== "@szmarczak/http-timer@^1.1.2": version "1.1.2" @@ -354,10 +353,10 @@ dependencies: source-map-support "^0.5.19" -"@truffle/codec@^0.7.1": - version "0.7.1" - resolved "https://registry.yarnpkg.com/@truffle/codec/-/codec-0.7.1.tgz#2ef0fa40109040796afbebb8812c872122100ae4" - integrity sha512-mNd6KnW6J0UB1zafGBXDlTEbCMvWpmPAJmzv7aF/nAIaN/F8UePSCiQ1OTQP39Rprj6GFiCCaWVnBAwum6UGSg== +"@truffle/codec@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@truffle/codec/-/codec-0.8.1.tgz#1f7b62a9d4063ed1b91ecb81d2d83be4ff97389d" + integrity sha512-X6BcpS97zpmLWRoAg9zJJIPoEiAJ3MRRJd5zf+qTmLbYXVhek9frreDMhs4WoaQSe3/DOYjVxtPmwmY4+alVvw== dependencies: big.js "^5.2.2" bn.js "^4.11.8" @@ -372,10 +371,10 @@ utf8 "^3.0.0" web3-utils "1.2.9" -"@truffle/contract-schema@^3.1.0", "@truffle/contract-schema@^3.3.1": - version "3.3.1" - resolved "https://registry.yarnpkg.com/@truffle/contract-schema/-/contract-schema-3.3.1.tgz#66385613d54d76df68a7a2c431fa9d352145a74b" - integrity sha512-xGBiYiCCW8hKuD/G8xb9w0WUuhdJDmQuz18A2Ens3Y8MO+jWA+Zw7xxZjCtiXAu9440Fj2V/BCXWcV6RxGKgBQ== +"@truffle/contract-schema@^3.1.0", "@truffle/contract-schema@^3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@truffle/contract-schema/-/contract-schema-3.3.2.tgz#6450738c35859ed087760d826031a8247f7bc907" + integrity sha512-PFNUHlcMFh6CDLDXTYCpm1G5rM5EJlneA9ml5y1TbkLgjLMICI2XLilimFZ/DC0THQekHpoQC+W/QMD/OTiTiw== dependencies: ajv "^6.10.0" crypto-js "^3.1.9-1" @@ -401,13 +400,13 @@ web3-utils "1.2.1" "@truffle/contract@^4.2.12": - version "4.2.28" - resolved "https://registry.yarnpkg.com/@truffle/contract/-/contract-4.2.28.tgz#1cde9706b41b77ac9070de1aa0f1bd7663705ddc" - integrity sha512-fjHcrVx/ZsAJD2ICNbn2dytwAqzcQUjHBB2k9/laCnk0S59TOK2md/NPGdapzXrbmlRzqWoWBNJXvbPHPbuACA== + version "4.2.31" + resolved "https://registry.yarnpkg.com/@truffle/contract/-/contract-4.2.31.tgz#85c6559a699a67ec0b2609c303981f503d97afec" + integrity sha512-wifJ343skGQpFJQlmRQyPRquguR0uDSIVaRPHXVsGnX+6p1BOGP2zhkSUjLo8WUqyfmw/1bZ/Z9GJZ7XM8PVOw== dependencies: "@truffle/blockchain-utils" "^0.0.25" - "@truffle/contract-schema" "^3.3.1" - "@truffle/debug-utils" "^4.2.14" + "@truffle/contract-schema" "^3.3.2" + "@truffle/debug-utils" "^5.0.2" "@truffle/error" "^0.0.11" "@truffle/interface-adapter" "^0.4.18" bignumber.js "^7.2.1" @@ -420,17 +419,17 @@ web3-eth-abi "1.2.9" web3-utils "1.2.9" -"@truffle/debug-utils@^4.2.14": - version "4.2.14" - resolved "https://registry.yarnpkg.com/@truffle/debug-utils/-/debug-utils-4.2.14.tgz#28431691bc3a96bad19e31733d957ac79059d4e7" - integrity sha512-g5UTX2DPTzrjRjBJkviGI2IrQRTTSvqjmNWCNZNXP+vgQKNxL9maLZhQ6oA3BuuByVW/kusgYeXt8+W1zynC8g== +"@truffle/debug-utils@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@truffle/debug-utils/-/debug-utils-5.0.2.tgz#566d6d8a2000325810ff57c9302abdb6b6740061" + integrity sha512-VTnbmTcjUKR0uctqUiPDlIt+R/7ix78hntSZku/qZ/EO/b1ts8W2fA0M2uPU+G8cicvvUpidg1z+qk/u844rDQ== dependencies: - "@truffle/codec" "^0.7.1" + "@truffle/codec" "^0.8.1" "@trufflesuite/chromafi" "^2.2.1" chalk "^2.4.2" debug "^4.1.0" highlight.js "^9.15.8" - highlightjs-solidity "^1.0.18" + highlightjs-solidity "^1.0.19" "@truffle/error@^0.0.11": version "0.0.11" @@ -443,9 +442,9 @@ integrity sha512-x55rtRuNfRO1azmZ30iR0pf0OJ6flQqbax1hJz+Avk1K5fdmOv5cr22s9qFnwTWnS6Bw0jvJEoR0ITsM7cPKtQ== "@truffle/hdwallet-provider@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@truffle/hdwallet-provider/-/hdwallet-provider-1.1.1.tgz#951f16cf3ca412c7c0e58efddb0eb0f32b127317" - integrity sha512-Gw5lk2dUs6NhLcaF49FuuL3Qv1Setpgr9uUhf7voIS/1OD4ar2CW9Zv7QJiR5m0PD/b8SUqbIckq0evY4Mendg== + version "1.2.0" + resolved "https://registry.yarnpkg.com/@truffle/hdwallet-provider/-/hdwallet-provider-1.2.0.tgz#7d4cc2038e1a2ca5cf08877f72a6383d14aff491" + integrity sha512-EPatDbyRuGbB/MLt9ZBokmtjyLjaNpuHfUIWuv4mQMrH1Nu82H5AAZYLh4Z1BZliDZpqB03a0yUMmK/4R0BN9g== dependencies: "@trufflesuite/web3-provider-engine" "15.0.13-1" "@types/web3" "^1.0.20" @@ -588,19 +587,19 @@ "@types/node" "*" "@types/node@*": - version "14.14.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.6.tgz#146d3da57b3c636cc0d1769396ce1cfa8991147f" - integrity sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw== + version "14.14.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.9.tgz#04afc9a25c6ff93da14deabd65dc44485b53c8d6" + integrity sha512-JsoLXFppG62tWTklIoO4knA+oDTYsmqWxHRvd4lpmfQRNhX6osheUOWETP2jMoV/2bEHuMra8Pp3Dmo/stBFcw== "@types/node@^10.0.3", "@types/node@^10.12.18", "@types/node@^10.3.2": - version "10.17.44" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.44.tgz#3945e6b702cb6403f22b779c8ea9e5c3f44ead40" - integrity sha512-vHPAyBX1ffLcy4fQHmDyIUMUb42gHZjPHU66nhvbMzAWJqHnySGZ6STwN3rwrnSd1FHB0DI/RWgGELgKSYRDmw== + version "10.17.46" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.46.tgz#1cd867ebfe9957ab45951f2f715f8de5f3dab7a3" + integrity sha512-Tice8a+sJtlP9C1EUo0DYyjq52T37b3LexVu3p871+kfIBIN+OQ7PKPei1oF3MgF39olEpUfxaLtD+QFc1k69Q== "@types/node@^12.12.6", "@types/node@^12.6.1": - version "12.19.3" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.3.tgz#a6e252973214079155f749e8bef99cc80af182fa" - integrity sha512-8Jduo8wvvwDzEVJCOvS/G6sgilOLvvhn1eMmK3TW8/T217O7u1jdrK6ImKLv80tVryaPSVeKu6sjDEiFjd4/eg== + version "12.19.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.6.tgz#fbf249fa46487dd8c7386d785231368b92a33a53" + integrity sha512-U2VopDdmBoYBmtm8Rz340mvvSz34VgX/K9+XCuckvcLGMkt3rbMX8soqFOikIPlPBc5lmw8By9NUK7bEFSBFlQ== "@types/node@^8.0.0": version "8.10.66" @@ -761,14 +760,15 @@ array-uniq@^1.0.3: integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= array.prototype.map@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.2.tgz#9a4159f416458a23e9483078de1106b2ef68f8ec" - integrity sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw== + version "1.0.3" + resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.3.tgz#1609623618d3d84134a37d4a220030c2bd18420b" + integrity sha512-nNcb30v0wfDyIe26Yif3PcV1JXQp4zEeEfupG7L4SRjnD6HLbO5b2a7eVSba53bOx4YCHYMBHt+Fp4vYstneRA== dependencies: + call-bind "^1.0.0" define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" + es-abstract "^1.18.0-next.1" es-array-method-boxes-properly "^1.0.0" - is-string "^1.0.4" + is-string "^1.0.5" asap@~2.0.6: version "2.0.6" @@ -842,9 +842,9 @@ aws-sign2@~0.7.0: integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= aws4@^1.8.0: - version "1.10.1" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.1.tgz#e1e82e4f3e999e2cfd61b161280d16a111f86428" - integrity sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA== + version "1.11.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== axios@0.19.2: version "0.19.2" @@ -873,9 +873,9 @@ base-x@^3.0.2, base-x@^3.0.8: safe-buffer "^5.0.1" base64-js@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== bcrypt-pbkdf@^1.0.0: version "1.0.2" @@ -951,7 +951,7 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.0, bn.js@^4.11.1, bn.js@^4.11.6, bn.js@^ resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== -bn.js@^5.1.1, bn.js@^5.1.2: +bn.js@^5.0.0, bn.js@^5.1.1, bn.js@^5.1.2: version "5.1.3" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.3.tgz#beca005408f642ebebea80b042b4d18d2ac0ee6b" integrity sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ== @@ -1047,11 +1047,11 @@ browserify-des@^1.0.0: safe-buffer "^5.1.2" browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== dependencies: - bn.js "^4.1.0" + bn.js "^5.0.0" randombytes "^2.0.1" browserify-sign@^4.0.0: @@ -1129,19 +1129,19 @@ buffer-xor@^1.0.3: integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= buffer@^5.0.5, buffer@^5.2.1, buffer@^5.5.0, buffer@^5.6.0: - version "5.7.0" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.0.tgz#88afbd29fc89fa7b58e82b39206f31f2cf34feed" - integrity sha512-cd+5r1VLBwUqTrmnzW+D7ABkJUM6mr7uv1dv+6jRw4Rcl7tFIFHDqHPL98LhpGFn3dbAt3gtLxtrWp4m1kFrqg== + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== dependencies: base64-js "^1.3.1" ieee754 "^1.1.13" bufferutil@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.1.tgz#3a177e8e5819a1243fe16b63a199951a7ad8d4a7" - integrity sha512-xowrxvpxojqkagPcWRQVXZl0YXhRhAtBEIq3VoER1NH5Mw1n1o0ojdspp+GS2J//2gCVyrzQDApQ4unGF+QOoA== + version "4.0.2" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.2.tgz#79f68631910f6b993d870fc77dc0a2894eb96cd5" + integrity sha512-AtnG3W6M8B2n4xDQ5R+70EXvOpnXsFYg/AK2yTZd+HQ/oxAdz+GI+DvjmhBw3L0ole+LJ0ngqY4JMbDzkfNzhA== dependencies: - node-gyp-build "~3.7.0" + node-gyp-build "^4.2.0" bytes@3.1.0: version "3.1.0" @@ -1161,6 +1161,14 @@ cacheable-request@^6.0.0: normalize-url "^4.1.0" responselike "^1.0.2" +call-bind@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.0.tgz#24127054bb3f9bdcb4b1fb82418186072f77b8ce" + integrity sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.0" + camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" @@ -1582,7 +1590,7 @@ debug@2.6.9, debug@^2.2.0: dependencies: ms "2.0.0" -debug@3.2.6, debug@^3.1.0: +debug@3.2.6: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== @@ -1603,10 +1611,17 @@ debug@=3.1.0: dependencies: ms "2.0.0" +debug@^3.1.0: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + debug@^4.1.0, debug@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" - integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg== + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== dependencies: ms "2.1.2" @@ -1913,7 +1928,7 @@ errno@~0.1.1: dependencies: prr "~1.0.1" -es-abstract@^1.17.0-next.1, es-abstract@^1.17.4: +es-abstract@^1.17.0-next.1: version "1.17.7" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.7.tgz#a4de61b2f66989fc7421676c1cb9787573ace54c" integrity sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g== @@ -1930,7 +1945,7 @@ es-abstract@^1.17.0-next.1, es-abstract@^1.17.4: string.prototype.trimend "^1.0.1" string.prototype.trimstart "^1.0.1" -es-abstract@^1.18.0-next.0, es-abstract@^1.18.0-next.1: +es-abstract@^1.18.0-next.1: version "1.18.0-next.1" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68" integrity sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA== @@ -1954,11 +1969,12 @@ es-array-method-boxes-properly@^1.0.0: integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== es-get-iterator@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.0.tgz#bb98ad9d6d63b31aacdc8f89d5d0ee57bcb5b4c8" - integrity sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ== + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.1.tgz#b93ddd867af16d5118e00881396533c1c6647ad9" + integrity sha512-qorBw8Y7B15DVLaJWy6WdEV/ZkieBcu6QCq/xzWzGOKJqgG1j754vXRfZ3NY7HSShneqU43mPB4OkQBTkvHhFw== dependencies: - es-abstract "^1.17.4" + call-bind "^1.0.0" + get-intrinsic "^1.0.1" has-symbols "^1.0.1" is-arguments "^1.0.4" is-map "^2.0.1" @@ -2625,9 +2641,9 @@ forwarded@~0.1.2: integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= fp-ts@^2.7.1: - version "2.8.5" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-2.8.5.tgz#1b4247081ea066cc152b48a55a0bc13c30828701" - integrity sha512-g6do+Q/IQsxgsd2qU6+QnAbZaPR533seIbFyLGqWSxhNX4+F+cY37QdaYmMUOzekLOv/yg/2f15tc26tzDatgw== + version "2.8.6" + resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-2.8.6.tgz#1a0e6c3f29f5b0fbfa3120f034ea266aa73c811b" + integrity sha512-fGGpKf/Jy3UT4s16oM+hr/8F5QXFcZ+20NAvaZXH5Y5jsiLPMDCaNqffXq0z1Kr6ZUJj0346cH9tq+cI2SoJ4w== fresh@0.5.2: version "0.5.2" @@ -2699,6 +2715,15 @@ get-func-name@^2.0.0: resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= +get-intrinsic@^1.0.0, get-intrinsic@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.1.tgz#94a9768fcbdd0595a1c9273aacf4c89d075631be" + integrity sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + get-port@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" @@ -2902,14 +2927,14 @@ he@1.2.0, he@^1.1.1: integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== highlight.js@^9.12.0, highlight.js@^9.15.8: - version "9.18.3" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.18.3.tgz#a1a0a2028d5e3149e2380f8a865ee8516703d634" - integrity sha512-zBZAmhSupHIl5sITeMqIJnYCDfAEc3Gdkqj65wC1lpI468MMQeeQkhcIAvk+RylAkxrCcI9xy9piHiXeQ1BdzQ== + version "9.18.5" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.18.5.tgz#d18a359867f378c138d6819edfc2a8acd5f29825" + integrity sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA== -highlightjs-solidity@^1.0.18: - version "1.0.18" - resolved "https://registry.yarnpkg.com/highlightjs-solidity/-/highlightjs-solidity-1.0.18.tgz#3deb0593689a26fbadf98e631bf2cd305a6417c9" - integrity sha512-k15h0br4oCRT0F0jTRuZbimerVt5V4n0k25h7oWi0kVqlBNeXPbSr5ddw02/2ukJmYfB8jauFDmxSauJjwM7Eg== +highlightjs-solidity@^1.0.19: + version "1.0.19" + resolved "https://registry.yarnpkg.com/highlightjs-solidity/-/highlightjs-solidity-1.0.19.tgz#a2f05bcfadd295a8eefb9cc20dcb18a3ba48e49c" + integrity sha512-ZIzMlxZxkcNnzWC1LeOeUjQjywzXnGyDxexOPKzz8hWFqdE2uRvz1BxD0joOkr41z4SU2ABXVGDx6EWlbzTBLQ== hmac-drbg@^1.0.0: version "1.0.1" @@ -3067,19 +3092,19 @@ is-binary-path@~2.1.0: binary-extensions "^2.0.0" is-buffer@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" - integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== + version "2.0.5" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" + integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== is-callable@^1.1.4, is-callable@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9" integrity sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA== -is-core-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.0.0.tgz#58531b70aed1db7c0e8d4eb1a0a2d1ddd64bd12d" - integrity sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw== +is-core-module@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.1.0.tgz#a4cc031d9b1aca63eecbd18a650e13cb4eeab946" + integrity sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA== dependencies: has "^1.0.3" @@ -3172,7 +3197,7 @@ is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0, is-stream@~1.1.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= -is-string@^1.0.4, is-string@^1.0.5: +is-string@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== @@ -3282,9 +3307,9 @@ json-buffer@3.0.0: integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= json-rpc-engine@^5.1.3: - version "5.3.0" - resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-5.3.0.tgz#7dc7291766b28766ebda33eb6d3f4c6301c44ff4" - integrity sha512-+diJ9s8rxB+fbJhT7ZEf8r8spaLRignLd8jTgQ/h5JSGppAHGtNMZtCoabipCaleR1B3GTGxbXBOqhaJSGmPGQ== + version "5.4.0" + resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-5.4.0.tgz#75758609d849e1dba1e09021ae473f3ab63161e5" + integrity sha512-rAffKbPoNDjuRnXkecTjnsE3xLLrb00rEkdgalINhaYVYIxDwWtvYBr9UFbhTvPB1B2qUOLoFd/cV6f4Q7mh7g== dependencies: eth-rpc-errors "^3.0.0" safe-event-emitter "^1.0.1" @@ -3864,11 +3889,6 @@ node-gyp-build@^4.2.0: resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.3.tgz#ce6277f853835f718829efb47db20f3e4d9c4739" integrity sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg== -node-gyp-build@~3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-3.7.0.tgz#daa77a4f547b9aed3e2aac779eaf151afd60ec8d" - integrity sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w== - nofilter@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-1.0.4.tgz#78d6f4b6a613e7ced8b015cec534625f7667006e" @@ -3935,12 +3955,12 @@ object.assign@4.1.0: object-keys "^1.0.11" object.assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.1.tgz#303867a666cdd41936ecdedfb1f8f3e32a478cdd" - integrity sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA== + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== dependencies: + call-bind "^1.0.0" define-properties "^1.1.3" - es-abstract "^1.18.0-next.0" has-symbols "^1.0.1" object-keys "^1.1.1" @@ -4487,11 +4507,11 @@ resolve-from@^3.0.0: integrity sha1-six699nWiBvItuZTM17rywoYh0g= resolve@^1.8.1: - version "1.18.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.18.1.tgz#018fcb2c5b207d2a6424aee361c5a266da8f4130" - integrity sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA== + version "1.19.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" + integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== dependencies: - is-core-module "^2.0.0" + is-core-module "^2.1.0" path-parse "^1.0.6" responselike@^1.0.2: @@ -4738,9 +4758,9 @@ simple-get@^2.7.0: simple-concat "^1.0.0" solidity-ast@^0.4.4: - version "0.4.12" - resolved "https://registry.yarnpkg.com/solidity-ast/-/solidity-ast-0.4.12.tgz#a3b4dabc73231f9c895d8a22c07f176355952382" - integrity sha512-D+Q16dABMDB9KgwU1XmBqWWdE9e4X4oPbquQ1N/bnmthGI7PCcckwXCXS+5rkXp+4ZITXk7e5XjI6fhODdk+yg== + version "0.4.14" + resolved "https://registry.yarnpkg.com/solidity-ast/-/solidity-ast-0.4.14.tgz#fc1cf28209cbfb77f7643fdc6c64f3e170f97207" + integrity sha512-kYVMtxSdcP5uy3kftOoV1xkXFlLcGM+yj2LVZHzuqiZMKGap3tL5HCv6WJaciShoddMUBuXjd9graodGD1VNlg== source-map-support@^0.5.16, source-map-support@^0.5.19: version "0.5.19" @@ -5074,9 +5094,9 @@ truffle-flattener@^1.5.0: tsort "0.0.1" truffle-plugin-verify@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/truffle-plugin-verify/-/truffle-plugin-verify-0.5.0.tgz#4ac8bc4edb1672c98a77a301a55362c6a7e859a4" - integrity sha512-VDT0FlFZisceRMrmlkKKiN/EmvFI6n6piAq9PQTrqWX6DdC64cE1RpmeLewIqL5L+5CVeLcApJMd58BpLUqNJg== + version "0.5.1" + resolved "https://registry.yarnpkg.com/truffle-plugin-verify/-/truffle-plugin-verify-0.5.1.tgz#07a23056e682b09605d75f2d67a981e74c59009b" + integrity sha512-Rc+tD4WrcxyRYtou6azXcrrjfVKb3q1APgcWYkC+8WOWyh1EEFRF1BQO4DQ8Ljk607yW0fS/w+DRQZfJnE7Skg== dependencies: axios "0.19.2" cli-logger "0.5.40" @@ -5084,9 +5104,9 @@ truffle-plugin-verify@^0.5.0: querystring "0.2.0" truffle@^5.1.47: - version "5.1.51" - resolved "https://registry.yarnpkg.com/truffle/-/truffle-5.1.51.tgz#5d10b27a79c1e7dd4d61df09eee0ef4d6b70120e" - integrity sha512-Sbw+FF2AfEvkcL/iOFm8UQPfuAfQ695UgxRliBE5sb7WoIN1IwRS0l0Cw+n8XOhkLTxOpoFtVEmrbdqWkZTz7g== + version "5.1.54" + resolved "https://registry.yarnpkg.com/truffle/-/truffle-5.1.54.tgz#e92bf801f1d75136aced8d7b75d8bd5ad94f2c70" + integrity sha512-9jl1jk3oIvWR7F5meh1FTyGV9qPh5GYbPdbrvaLgSUevMLUxnaMtWK6ZRcoVUG9zC0mY4uPL/brzb9nt+4LKJA== dependencies: app-module-path "^2.2.0" mocha "8.1.2" @@ -5209,11 +5229,11 @@ url-to-options@^1.0.1: integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= utf-8-validate@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.2.tgz#63cfbccd85dc1f2b66cf7a1d0eebc08ed056bfb3" - integrity sha512-SwV++i2gTD5qh2XqaPzBnNX88N6HdyhQrNNRykvcS0QKvItV9u3vPEJr+X5Hhfb1JC0r0e1alL0iB09rY8+nmw== + version "5.0.3" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.3.tgz#3b64e418ad2ff829809025fdfef595eab2f03a27" + integrity sha512-jtJM6fpGv8C1SoH4PtG22pGto6x+Y8uPprW0tw3//gGFhDDTiuksgradgFN6yRayDP4SyZZa6ZMGHLIa17+M8A== dependencies: - node-gyp-build "~3.7.0" + node-gyp-build "^4.2.0" utf8@3.0.0, utf8@^3.0.0: version "3.0.0" From 13fa58f2cdc6899b636973f2cbad1d20962d7781 Mon Sep 17 00:00:00 2001 From: Sebastian Kim Date: Fri, 20 Nov 2020 17:25:50 +0900 Subject: [PATCH 6/7] Add claimWRNandBonus() utility function --- contracts/WRNRewardPool.sol | 5 +++++ test/WRNRewardPool.test.js | 27 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/contracts/WRNRewardPool.sol b/contracts/WRNRewardPool.sol index 1b4f641..29ad6dd 100644 --- a/contracts/WRNRewardPool.sol +++ b/contracts/WRNRewardPool.sol @@ -227,6 +227,11 @@ contract WRNRewardPool is LockUpPool { emit WRNClaimed(tokenAddress, msg.sender, amount, block.timestamp); } + function claimWRNandBonus(address tokenAddress) external { + claimWRN(tokenAddress); + claimBonus(tokenAddress); + } + // Reserved storage space to allow for layout changes in the future. uint256[50] private ______gap; } diff --git a/test/WRNRewardPool.test.js b/test/WRNRewardPool.test.js index 5449d0f..c47333b 100644 --- a/test/WRNRewardPool.test.js +++ b/test/WRNRewardPool.test.js @@ -379,4 +379,31 @@ contract('WRN Reward Pool Test', ([creator, alice, bob]) => { assert.equal((await this.wrnRewardPool.pendingWRN(this.hunt.address, { from: alice })).valueOf() / 1e18, 0.25); assert.equal((await this.wrnRewardPool.pendingWRN(this.hunt.address, { from: bob })).valueOf() / 1e18, 0.5625); }); + + it('should be able to cliam pending WRN and bonus at once', async () => { + await this.wrnRewardPool.doLockUp(this.hunt.address, toBN(100), 3, { from: alice }); + // Block 1 - alice: 0 + await this.wrnRewardPool.doLockUp(this.hunt.address, toBN(100), 3, { from: bob }); + // Block 1 - alice: 0.5 / bob: 0 + assert.equal((await this.wrnRewardPool.pendingWRN(this.hunt.address, { from: alice })).valueOf() / 1e18, 0.5); + assert.equal((await this.wrnRewardPool.pendingWRN(this.hunt.address, { from: bob })).valueOf() / 1e18, 0); + + await this.wrnRewardPool.exit(this.hunt.address, 0, true, { from: alice }); + // Block 2 - alice: 0.75 / bob: 0.25 + // Penalty generated: +10 HUNT + assert.equal((await this.wrn.balanceOf(alice)).valueOf() / 1e18, 0.75); + assert.equal((await this.hunt.balanceOf(alice)).valueOf() / 1e18, 487); + + await this.wrnRewardPool.claimWRNandBonus(this.hunt.address, { from: bob }); + // Block 3 - bob: 0.75 + + assert.equal((await this.wrn.balanceOf(bob)).valueOf() / 1e18, 0.75); + assert.equal((await this.hunt.balanceOf(bob)).valueOf() / 1e18, 410); // 500 - 100 + 10 + + // Additional checks (duplicated) + assert.equal((await this.wrn.totalSupply()).valueOf() / 1e18, 1.5 + 1.5/9); + const fundAddress = await this.wrnRewardPool.fundAddress().valueOf(); + assert.equal((await this.wrn.balanceOf(fundAddress)).valueOf() / 1e18, 1.5/9); + assert.equal((await this.hunt.balanceOf(fundAddress)).valueOf() / 1e18, 3); + }); }); From ea243ff3fe785d7fff801fe5eac510204bf55d02 Mon Sep 17 00:00:00 2001 From: Sebastian Kim Date: Fri, 20 Nov 2020 18:39:51 +0900 Subject: [PATCH 7/7] Test changeProxyAdmin --- README.md | 52 +++++++++++++------------- contracts/test/WRNRewardPoolV2Test.sol | 5 +++ test/Upgrade.test.js | 20 ++++++++-- truffle-config.js | 4 +- 4 files changed, 49 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 22e722f..dd06664 100644 --- a/README.md +++ b/README.md @@ -34,60 +34,60 @@ A governance token distribution contract on top of LockUpPool. A maximum of 1.2M ·------------------------------------------------|---------------------------|--------------|----------------------------· | Solc version: 0.7.1+commit.f4a555be · Optimizer enabled: true · Runs: 1500 · Block limit: 6718946 gas │ ·················································|···························|··············|····························· -| Methods · 25 gwei/gas · 484.30 usd/eth │ +| Methods · 25 gwei/gas · 495.45 usd/eth │ ························|························|·············|·············|··············|··············|·············· | Contract · Method · Min · Max · Avg · # calls · usd (avg) │ ························|························|·············|·············|··············|··············|·············· -| ERC20Token · addMinter · 72827 · 75612 · 73098 · 32 · 0.89 │ +| ERC20Token · addMinter · 72815 · 75612 · 73164 · 34 · 0.91 │ ························|························|·············|·············|··············|··············|·············· -| ERC20Token · approve · 29070 · 46897 · 43962 · 129 · 0.53 │ +| ERC20Token · approve · 29070 · 46897 · 43988 · 133 · 0.54 │ ························|························|·············|·············|··············|··············|·············· -| ERC20Token · initialize · 324430 · 369343 · 356528 · 102 · 4.32 │ +| ERC20Token · initialize · 324430 · 369343 · 356342 · 104 · 4.41 │ ························|························|·············|·············|··············|··············|·············· -| ERC20Token · mint · - · - · 52871 · 49 · 0.64 │ +| ERC20Token · mint · - · - · 52871 · 51 · 0.65 │ ························|························|·············|·············|··············|··············|·············· -| ERC20Token · transfer · 37081 · 52141 · 51421 · 21 · 0.62 │ +| ERC20Token · transfer · 37081 · 52141 · 51421 · 21 · 0.64 │ ························|························|·············|·············|··············|··············|·············· -| LockUpPool · addLockUpPool · 71215 · 86311 · 84684 · 37 · 1.03 │ +| LockUpPool · addLockUpPool · 71227 · 86311 · 84684 · 37 · 1.05 │ ························|························|·············|·············|··············|··············|·············· -| LockUpPool · claimBonus · 26634 · 105197 · 64009 · 3 · 0.77 │ +| LockUpPool · claimBonus · 26634 · 105197 · 64009 · 3 · 0.79 │ ························|························|·············|·············|··············|··············|·············· -| LockUpPool · doLockUp · 185088 · 350039 · 297643 · 46 · 3.60 │ +| LockUpPool · doLockUp · 185088 · 350039 · 297644 · 46 · 3.69 │ ························|························|·············|·············|··············|··············|·············· -| LockUpPool · exit · 58256 · 207065 · 134292 · 31 · 1.63 │ +| LockUpPool · exit · 58250 · 207065 · 134293 · 31 · 1.66 │ ························|························|·············|·············|··············|··············|·············· -| LockUpPool · initialize · - · - · 116378 · 31 · 1.41 │ +| LockUpPool · initialize · - · - · 116378 · 31 · 1.44 │ ························|························|·············|·············|··············|··············|·············· -| LockUpPool · setEmergencyMode · - · - · 28217 · 4 · 0.34 │ +| LockUpPool · setEmergencyMode · - · - · 28217 · 4 · 0.35 │ ························|························|·············|·············|··············|··············|·············· -| LockUpPool · updateMaxLimit · 28764 · 28836 · 28800 · 2 · 0.35 │ +| LockUpPool · updateMaxLimit · 28764 · 28836 · 28800 · 2 · 0.36 │ ························|························|·············|·············|··············|··············|·············· | Migrations · setCompleted · - · - · 21204 · 5 · 0.26 │ ························|························|·············|·············|··············|··············|·············· -| WRNRewardPool · addLockUpRewardPool · 101166 · 224459 · 121812 · 39 · 1.47 │ +| WRNRewardPool · addLockUpRewardPool · 101166 · 224459 · 121603 · 41 · 1.51 │ ························|························|·············|·············|··············|··············|·············· -| WRNRewardPool · claimWRN · 146843 · 202655 · 184051 · 6 · 2.23 │ +| WRNRewardPool · claimWRN · 146854 · 202654 · 184054 · 6 · 2.28 │ ························|························|·············|·············|··············|··············|·············· -| WRNRewardPool · doLockUp · 304647 · 422522 · 390196 · 30 · 4.72 │ +| WRNRewardPool · claimWRNandBonus · - · - · 200393 · 1 · 2.48 │ ························|························|·············|·············|··············|··············|·············· -| WRNRewardPool · exit · 159206 · 290450 · 245126 · 7 · 2.97 │ +| WRNRewardPool · doLockUp · 304635 · 422522 · 391213 · 32 · 4.85 │ ························|························|·············|·············|··············|··············|·············· -| WRNRewardPool · initialize · 241822 · 241954 · 241873 · 29 · 2.93 │ +| WRNRewardPool · exit · 159193 · 290449 · 250260 · 8 · 3.10 │ ························|························|·············|·············|··············|··············|·············· -| WRNRewardPool · setEmergencyMode · - · - · 28218 · 1 · 0.34 │ +| WRNRewardPool · initialize · 241834 · 241954 · 241873 · 30 · 3.00 │ ························|························|·············|·············|··············|··············|·············· -| WRNRewardPool · updatePoolMultiplier · - · - · 223728 · 1 · 2.71 │ +| WRNRewardPool · setEmergencyMode · - · - · 28218 · 1 · 0.35 │ ························|························|·············|·············|··············|··············|·············· -| WRNRewardPoolV2Test · setVarAdded · - · - · 44247 · 1 · 0.54 │ +| WRNRewardPool · updatePoolMultiplier · - · - · 223728 · 1 · 2.77 │ +························|························|·············|·············|··············|··············|·············· +| WRNRewardPoolV2Test · setVarAdded · - · - · 44269 · 2 · 0.55 │ ························|························|·············|·············|··············|··············|·············· | Deployments · · % of limit · │ ·················································|·············|·············|··············|··············|·············· -| ERC20Token · - · - · 1926451 · 28.7 % · 23.32 │ -·················································|·············|·············|··············|··············|·············· -| LockUpPool · - · - · 1950515 · 29 % · 23.62 │ +| ERC20Token · - · - · 1926451 · 28.7 % · 23.86 │ ·················································|·············|·············|··············|··············|·············· -| WRNRewardPool · - · - · 2677676 · 39.9 % · 32.42 │ +| LockUpPool · - · - · 1950515 · 29 % · 24.16 │ ·················································|·············|·············|··············|··············|·············· -| WRNRewardPoolV2Test · - · - · 2446820 · 36.4 % · 29.62 │ +| WRNRewardPool · - · - · 2696051 · 40.1 % · 33.39 │ ·------------------------------------------------|-------------|-------------|--------------|--------------|-------------· ``` diff --git a/contracts/test/WRNRewardPoolV2Test.sol b/contracts/test/WRNRewardPoolV2Test.sol index 3064fdf..9fba188 100644 --- a/contracts/test/WRNRewardPoolV2Test.sol +++ b/contracts/test/WRNRewardPoolV2Test.sol @@ -238,6 +238,11 @@ contract WRNRewardPoolV2Test is LockUpPool { emit WRNClaimed(tokenAddress, msg.sender, amount, block.timestamp); } + function claimWRNandBonus(address tokenAddress) external { + claimWRN(tokenAddress); + claimBonus(tokenAddress); + } + // V2: Changed from 50 -> 49 uint256[49] private ______gap; } diff --git a/test/Upgrade.test.js b/test/Upgrade.test.js index 3cc97bd..5946797 100644 --- a/test/Upgrade.test.js +++ b/test/Upgrade.test.js @@ -1,8 +1,8 @@ -const ERC20Token = artifacts.require('ERC20Token'); + const ERC20Token = artifacts.require('ERC20Token'); const WRNRewardPool = artifacts.require('WRNRewardPool'); const WRNRewardPoolV2Test = artifacts.require('WRNRewardPoolV2Test'); const { expectRevert, time } = require('@openzeppelin/test-helpers'); -const { deployProxy, upgradeProxy } = require('@openzeppelin/truffle-upgrades'); +const { deployProxy, upgradeProxy, admin } = require('@openzeppelin/truffle-upgrades'); contract('WRNRewardPoolV2Test with upgrades plugin', ([creator, alice]) => { beforeEach(async () => { @@ -15,15 +15,15 @@ contract('WRNRewardPoolV2Test with upgrades plugin', ([creator, alice]) => { await this.wrn.addMinter(this.wrnRewardPool.address); await this.wrnRewardPool.addLockUpRewardPool(this.hunt.address, 2, 9999999999999, false); await this.hunt.approve(this.wrnRewardPool.address, 9999999999999); - - this.wrnRewardPoolV2 = await upgradeProxy(this.wrnRewardPool.address, WRNRewardPoolV2Test, { unsafeAllowCustomTypes: true }); }); it('should have the same proxy address', async () => { + this.wrnRewardPoolV2 = await upgradeProxy(this.wrnRewardPool.address, WRNRewardPoolV2Test, { unsafeAllowCustomTypes: true }); assert.equal(this.wrnRewardPool.address, this.wrnRewardPoolV2.address); }); it('should disable exit function', async () => { + this.wrnRewardPoolV2 = await upgradeProxy(this.wrnRewardPool.address, WRNRewardPoolV2Test, { unsafeAllowCustomTypes: true }); await expectRevert( this.wrnRewardPool.exit(this.hunt.address, 0, true), // Should be able to call with the same proxy contract 'disabled' @@ -31,7 +31,19 @@ contract('WRNRewardPoolV2Test with upgrades plugin', ([creator, alice]) => { }); it('should have a new extended variable', async () => { + this.wrnRewardPoolV2 = await upgradeProxy(this.wrnRewardPool.address, WRNRewardPoolV2Test, { unsafeAllowCustomTypes: true }); await this.wrnRewardPoolV2.setVarAdded(1234); // Should call with the new V2 contract because this function is added (ABI is changed) assert.equal((await this.wrnRewardPoolV2.varAdded()).valueOf(), 1234); }); + + it('should fail if non-admin user try to upgrade', async () => { + await admin.changeProxyAdmin(this.wrnRewardPool.address, alice); + + await expectRevert( + upgradeProxy(this.wrnRewardPool.address, WRNRewardPoolV2Test, { unsafeAllowCustomTypes: true }), + 'Proxy admin is not the one registered in the network manifest' + ); + }); + + // TODO: How can we renounce ownership? - await admin.transferProxyAdminOwnership('0x0000000000000000000000000000000000000000')? }); \ No newline at end of file diff --git a/truffle-config.js b/truffle-config.js index a50916b..3cb7855 100644 --- a/truffle-config.js +++ b/truffle-config.js @@ -50,8 +50,8 @@ module.exports = { reporter: 'eth-gas-reporter', reporterOptions : { currency: 'USD', - coinmarketcap: '793664cd-7f8f-470f-867b-9de05f7d411d' - // gasPrice: 25 + coinmarketcap: '793664cd-7f8f-470f-867b-9de05f7d411d', + gasPrice: 25 } }, api_keys: {