From bfd989400c8aa4ff694b886731f77ad0a37a5b6b Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 20 Feb 2024 16:14:08 +0800 Subject: [PATCH 1/9] use constant address --- src/KTONStakingRewards.sol | 9 +-------- src/RewardsDistributionRecipient.sol | 3 ++- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/KTONStakingRewards.sol b/src/KTONStakingRewards.sol index 392219d..866e3e6 100644 --- a/src/KTONStakingRewards.sol +++ b/src/KTONStakingRewards.sol @@ -16,7 +16,7 @@ contract KTONStakingRewards is IStakingRewards, RewardsDistributionRecipient, Re /* ========== STATE VARIABLES ========== */ - IERC20 public stakingToken; + IERC20 public constant stakingToken = IERC20(0x0000000000000000000000000000000000000402); uint256 public periodFinish = 0; uint256 public rewardRate = 0; uint256 public rewardsDuration = 7200; @@ -29,13 +29,6 @@ contract KTONStakingRewards is IStakingRewards, RewardsDistributionRecipient, Re uint256 private _totalSupply; mapping(address => uint256) private _balances; - /* ========== CONSTRUCTOR ========== */ - - constructor(address _rewardsDistribution, address _stakingToken) public { - stakingToken = IERC20(_stakingToken); - rewardsDistribution = _rewardsDistribution; - } - /* ========== VIEWS ========== */ function totalSupply() external view returns (uint256) { diff --git a/src/RewardsDistributionRecipient.sol b/src/RewardsDistributionRecipient.sol index b312107..9319fb8 100644 --- a/src/RewardsDistributionRecipient.sol +++ b/src/RewardsDistributionRecipient.sol @@ -1,7 +1,8 @@ pragma solidity ^0.5.16; contract RewardsDistributionRecipient { - address public rewardsDistribution; + // "KTONStakingRewards" in bytes. + address public constant rewardsDistribution = 0x4b544f4e5374616b696e67526577617264730000; function notifyRewardAmount() external payable; From 8f3c33ceb9b35b90d821e986aab4574d47c05cac Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 20 Feb 2024 16:23:36 +0800 Subject: [PATCH 2/9] revert #3 and fix #4 --- flat/IStakingRewards.f.sol | 32 +++++++++++++++++++++++++ flat/KTONStakingRewards.f.sol | 18 ++++---------- flat/RewardsDistributionRecipient.f.sol | 19 +++++++++++++++ src/KTONStakingRewards.sol | 4 +--- src/RewardsDistributionRecipient.sol | 6 ++--- 5 files changed, 60 insertions(+), 19 deletions(-) create mode 100644 flat/IStakingRewards.f.sol create mode 100644 flat/RewardsDistributionRecipient.f.sol diff --git a/flat/IStakingRewards.f.sol b/flat/IStakingRewards.f.sol new file mode 100644 index 0000000..9abf8ba --- /dev/null +++ b/flat/IStakingRewards.f.sol @@ -0,0 +1,32 @@ +// hevm: flattened sources of src/interfaces/IStakingRewards.sol + +pragma solidity >=0.4.24; + +////// src/interfaces/IStakingRewards.sol +/* pragma solidity >=0.4.24; */ + +interface IStakingRewards { + // Views + function lastTimeRewardApplicable() external view returns (uint256); + + function rewardPerToken() external view returns (uint256); + + function earned(address account) external view returns (uint256); + + function getRewardForDuration() external view returns (uint256); + + function totalSupply() external view returns (uint256); + + function balanceOf(address account) external view returns (uint256); + + // Mutative + + function stake(uint256 amount) external; + + function withdraw(uint256 amount) external; + + function getReward() external; + + function exit() external; +} + diff --git a/flat/KTONStakingRewards.f.sol b/flat/KTONStakingRewards.f.sol index 22d4aa7..2788d17 100644 --- a/flat/KTONStakingRewards.f.sol +++ b/flat/KTONStakingRewards.f.sol @@ -426,9 +426,10 @@ contract ReentrancyGuard { /* pragma solidity ^0.5.16; */ contract RewardsDistributionRecipient { - address public rewardsDistribution; + // "sc/ktnstk" in bytes. + address public constant rewardsDistribution = 0x73632F6b746e73746B0000000000000000000000; - function notifyRewardAmount() external payable; + function notifyRewardAmount() external; modifier onlyRewardsDistribution() { require(msg.sender == rewardsDistribution, "Caller is not RewardsDistribution contract"); @@ -483,7 +484,7 @@ contract KTONStakingRewards is IStakingRewards, RewardsDistributionRecipient, Re /* ========== STATE VARIABLES ========== */ - IERC20 public stakingToken; + IERC20 public constant stakingToken = IERC20(0x0000000000000000000000000000000000000402); uint256 public periodFinish = 0; uint256 public rewardRate = 0; uint256 public rewardsDuration = 7200; @@ -496,13 +497,6 @@ contract KTONStakingRewards is IStakingRewards, RewardsDistributionRecipient, Re uint256 private _totalSupply; mapping(address => uint256) private _balances; - /* ========== CONSTRUCTOR ========== */ - - constructor(address _rewardsDistribution, address _stakingToken) public { - stakingToken = IERC20(_stakingToken); - rewardsDistribution = _rewardsDistribution; - } - /* ========== VIEWS ========== */ function totalSupply() external view returns (uint256) { @@ -570,9 +564,7 @@ contract KTONStakingRewards is IStakingRewards, RewardsDistributionRecipient, Re /* ========== RESTRICTED FUNCTIONS ========== */ - function notifyRewardAmount() external payable onlyRewardsDistribution updateReward(address(0)) { - uint256 reward = msg.value; - require(reward >= rewardsDuration, "Provided reward too low"); + function notifyRewardAmount(uint256 reward) external onlyRewardsDistribution updateReward(address(0)) { if (block.timestamp >= periodFinish) { rewardRate = reward.div(rewardsDuration); } else { diff --git a/flat/RewardsDistributionRecipient.f.sol b/flat/RewardsDistributionRecipient.f.sol new file mode 100644 index 0000000..a5b14c7 --- /dev/null +++ b/flat/RewardsDistributionRecipient.f.sol @@ -0,0 +1,19 @@ +// hevm: flattened sources of src/RewardsDistributionRecipient.sol + +pragma solidity >=0.5.16 <0.6.0; + +////// src/RewardsDistributionRecipient.sol +/* pragma solidity ^0.5.16; */ + +contract RewardsDistributionRecipient { + // "sc/ktnstk" in bytes. + address public constant rewardsDistribution = 0x73632F6b746e73746B0000000000000000000000; + + function notifyRewardAmount() external; + + modifier onlyRewardsDistribution() { + require(msg.sender == rewardsDistribution, "Caller is not RewardsDistribution contract"); + _; + } +} + diff --git a/src/KTONStakingRewards.sol b/src/KTONStakingRewards.sol index 866e3e6..e719ba9 100644 --- a/src/KTONStakingRewards.sol +++ b/src/KTONStakingRewards.sol @@ -96,9 +96,7 @@ contract KTONStakingRewards is IStakingRewards, RewardsDistributionRecipient, Re /* ========== RESTRICTED FUNCTIONS ========== */ - function notifyRewardAmount() external payable onlyRewardsDistribution updateReward(address(0)) { - uint256 reward = msg.value; - require(reward >= rewardsDuration, "Provided reward too low"); + function notifyRewardAmount(uint256 reward) external onlyRewardsDistribution updateReward(address(0)) { if (block.timestamp >= periodFinish) { rewardRate = reward.div(rewardsDuration); } else { diff --git a/src/RewardsDistributionRecipient.sol b/src/RewardsDistributionRecipient.sol index 9319fb8..1c9d1e1 100644 --- a/src/RewardsDistributionRecipient.sol +++ b/src/RewardsDistributionRecipient.sol @@ -1,10 +1,10 @@ pragma solidity ^0.5.16; contract RewardsDistributionRecipient { - // "KTONStakingRewards" in bytes. - address public constant rewardsDistribution = 0x4b544f4e5374616b696e67526577617264730000; + // "sc/ktnstk" in bytes. + address public constant rewardsDistribution = 0x73632F6b746e73746B0000000000000000000000; - function notifyRewardAmount() external payable; + function notifyRewardAmount() external; modifier onlyRewardsDistribution() { require(msg.sender == rewardsDistribution, "Caller is not RewardsDistribution contract"); From c081b7da32dfed4ae172b39cb3b2628b8bf4949f Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 20 Feb 2024 16:25:07 +0800 Subject: [PATCH 3/9] clean --- flat/IStakingRewards.f.sol | 32 ------------------------- flat/RewardsDistributionRecipient.f.sol | 19 --------------- 2 files changed, 51 deletions(-) delete mode 100644 flat/IStakingRewards.f.sol delete mode 100644 flat/RewardsDistributionRecipient.f.sol diff --git a/flat/IStakingRewards.f.sol b/flat/IStakingRewards.f.sol deleted file mode 100644 index 9abf8ba..0000000 --- a/flat/IStakingRewards.f.sol +++ /dev/null @@ -1,32 +0,0 @@ -// hevm: flattened sources of src/interfaces/IStakingRewards.sol - -pragma solidity >=0.4.24; - -////// src/interfaces/IStakingRewards.sol -/* pragma solidity >=0.4.24; */ - -interface IStakingRewards { - // Views - function lastTimeRewardApplicable() external view returns (uint256); - - function rewardPerToken() external view returns (uint256); - - function earned(address account) external view returns (uint256); - - function getRewardForDuration() external view returns (uint256); - - function totalSupply() external view returns (uint256); - - function balanceOf(address account) external view returns (uint256); - - // Mutative - - function stake(uint256 amount) external; - - function withdraw(uint256 amount) external; - - function getReward() external; - - function exit() external; -} - diff --git a/flat/RewardsDistributionRecipient.f.sol b/flat/RewardsDistributionRecipient.f.sol deleted file mode 100644 index a5b14c7..0000000 --- a/flat/RewardsDistributionRecipient.f.sol +++ /dev/null @@ -1,19 +0,0 @@ -// hevm: flattened sources of src/RewardsDistributionRecipient.sol - -pragma solidity >=0.5.16 <0.6.0; - -////// src/RewardsDistributionRecipient.sol -/* pragma solidity ^0.5.16; */ - -contract RewardsDistributionRecipient { - // "sc/ktnstk" in bytes. - address public constant rewardsDistribution = 0x73632F6b746e73746B0000000000000000000000; - - function notifyRewardAmount() external; - - modifier onlyRewardsDistribution() { - require(msg.sender == rewardsDistribution, "Caller is not RewardsDistribution contract"); - _; - } -} - From fc0af85ce691f25960c3b13a5c1bb7bdea456472 Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 20 Feb 2024 16:48:23 +0800 Subject: [PATCH 4/9] fix --- src/RewardsDistributionRecipient.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RewardsDistributionRecipient.sol b/src/RewardsDistributionRecipient.sol index 1c9d1e1..f145197 100644 --- a/src/RewardsDistributionRecipient.sol +++ b/src/RewardsDistributionRecipient.sol @@ -4,7 +4,7 @@ contract RewardsDistributionRecipient { // "sc/ktnstk" in bytes. address public constant rewardsDistribution = 0x73632F6b746e73746B0000000000000000000000; - function notifyRewardAmount() external; + function notifyRewardAmount(uint256 reward) external; modifier onlyRewardsDistribution() { require(msg.sender == rewardsDistribution, "Caller is not RewardsDistribution contract"); From 09988ca4a6f3d6d4645d64c5f5770093a2c7a5c0 Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 20 Feb 2024 17:17:52 +0800 Subject: [PATCH 5/9] deploy on pangolin --- README.md | 2 +- bin/deploy.sh | 14 +++----------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 3c77298..383e9d9 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Staking pool for KTON. ## Addresses | NetWork | KTON Staker Deployment Address | |-----------|--------------------------------------------| -| Pangolin | 0x0000003f5bA7A4EA41655aDbC89c2A668d449128 | +| Pangolin | 0x0000000000F9180bB475E0673d7710beC1bc2Cc0 | ### API diff --git a/bin/deploy.sh b/bin/deploy.sh index 654ccc9..5389a1d 100644 --- a/bin/deploy.sh +++ b/bin/deploy.sh @@ -8,20 +8,12 @@ salt=0xfa22cbd0171eac53025c57496561ca39c3e6a4e8affe2848552ec79f85513fae c3=0x0000000000C76fe1798a428F60b27c6724e03408 deployer=0x0f14341A7f464320319025540E8Fe48Ad0fe5aec -KTON=0x0000000000000000000000000000000000000402 -STAKING_PALLET=0x6d6f646c64612f74727372790000000000000000 - -bytecode=$(jq -r ".contracts[\"src/KTONStakingRewards.sol\"].KTONStakingRewards.evm.bytecode.object" out/dapp.sol.json) -args=$(set -x; ethabi encode params \ - -v address "${STAKING_PALLET:2}" \ - -v address "${KTON:2}" -) -creationCode=0x$bytecode$args +bytecode=0x$(jq -r ".contracts[\"src/KTONStakingRewards.sol\"].KTONStakingRewards.evm.bytecode.object" out/dapp.sol.json) # salt, creationCode -expect_addr=$(seth call $c3 "deploy(bytes32,bytes)(address)" $salt $creationCode --chain $chain) +expect_addr=$(seth call $c3 "deploy(bytes32,bytes)(address)" $salt $bytecode --chain $chain) if [[ $(seth --to-checksum-address "${addr}") == $(seth --to-checksum-address "${expect_addr}") ]]; then - (set -x; seth send $c3 "deploy(bytes32,bytes)" $salt $creationCode --chain $chain) + (set -x; seth send $c3 "deploy(bytes32,bytes)" $salt $bytecode --chain $chain) else echo "Unexpected address." fi From 7c68d5748d6bd074b543b23e01cc18153d15c641 Mon Sep 17 00:00:00 2001 From: echo Date: Wed, 21 Feb 2024 14:28:45 +0800 Subject: [PATCH 6/9] Add RewardsDistribution --- README.md | 6 ++-- bin/deploy.sh | 4 +-- src/KTONStakingRewards.sol | 11 ++++-- src/Owned.sol | 34 +++++++++++++++++++ src/RewardsDistribution.sol | 22 ++++++++++++ src/RewardsDistributionRecipient.sol | 5 +-- .../IRewardsDistributionRecipient.sol | 5 +++ 7 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 src/Owned.sol create mode 100644 src/RewardsDistribution.sol create mode 100644 src/interfaces/IRewardsDistributionRecipient.sol diff --git a/README.md b/README.md index 383e9d9..00e5be2 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,9 @@ Forked from Staking pool for KTON. ## Addresses -| NetWork | KTON Staker Deployment Address | -|-----------|--------------------------------------------| -| Pangolin | 0x0000000000F9180bB475E0673d7710beC1bc2Cc0 | +| NetWork | KTONStakingRewards | | +|-----------|--------------------------------------------|-| +| Pangolin | 0x0000000000F9180bB475E0673d7710beC1bc2Cc0 || ### API diff --git a/bin/deploy.sh b/bin/deploy.sh index 5389a1d..3405063 100644 --- a/bin/deploy.sh +++ b/bin/deploy.sh @@ -3,8 +3,8 @@ set -eo pipefail chain=${1:?} -addr=0x0000000000F9180bB475E0673d7710beC1bc2Cc0 -salt=0xfa22cbd0171eac53025c57496561ca39c3e6a4e8affe2848552ec79f85513fae +addr=0x0000004B21061Ce4C13138C41c3ad694500129cc +salt=0x65fd4e09846a2c80c9661aea1c7662ec870ec1814392afcf88b4454be0e1ce17 c3=0x0000000000C76fe1798a428F60b27c6724e03408 deployer=0x0f14341A7f464320319025540E8Fe48Ad0fe5aec diff --git a/src/KTONStakingRewards.sol b/src/KTONStakingRewards.sol index e719ba9..95adb7d 100644 --- a/src/KTONStakingRewards.sol +++ b/src/KTONStakingRewards.sol @@ -19,7 +19,7 @@ contract KTONStakingRewards is IStakingRewards, RewardsDistributionRecipient, Re IERC20 public constant stakingToken = IERC20(0x0000000000000000000000000000000000000402); uint256 public periodFinish = 0; uint256 public rewardRate = 0; - uint256 public rewardsDuration = 7200; + uint256 public rewardsDuration = 7 days; uint256 public lastUpdateTime; uint256 public rewardPerTokenStored; @@ -29,6 +29,12 @@ contract KTONStakingRewards is IStakingRewards, RewardsDistributionRecipient, Re uint256 private _totalSupply; mapping(address => uint256) private _balances; + /* ========== CONSTRUCTOR ========== */ + + constructor(address _rewardsDistribution) public { + rewardsDistribution = _rewardsDistribution; + } + /* ========== VIEWS ========== */ function totalSupply() external view returns (uint256) { @@ -96,7 +102,8 @@ contract KTONStakingRewards is IStakingRewards, RewardsDistributionRecipient, Re /* ========== RESTRICTED FUNCTIONS ========== */ - function notifyRewardAmount(uint256 reward) external onlyRewardsDistribution updateReward(address(0)) { + function notifyRewardAmount() external payable onlyRewardsDistribution updateReward(address(0)) { + uint256 reward = msg.value; if (block.timestamp >= periodFinish) { rewardRate = reward.div(rewardsDuration); } else { diff --git a/src/Owned.sol b/src/Owned.sol new file mode 100644 index 0000000..c340976 --- /dev/null +++ b/src/Owned.sol @@ -0,0 +1,34 @@ +pragma solidity ^0.5.16; + + +// https://github.com/Synthetixio/synthetix/blob/v2.27.2/contracts/Owned.sol +contract Owned { + address public owner; + address public nominatedOwner; + + constructor(address _owner) public { + require(_owner != address(0), "Owner address cannot be 0"); + owner = _owner; + emit OwnerChanged(address(0), _owner); + } + + function nominateNewOwner(address _owner) external onlyOwner { + nominatedOwner = _owner; + emit OwnerNominated(_owner); + } + + function acceptOwnership() external { + require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership"); + emit OwnerChanged(owner, nominatedOwner); + owner = nominatedOwner; + nominatedOwner = address(0); + } + + modifier onlyOwner { + require(msg.sender == owner, "Only the contract owner may perform this action"); + _; + } + + event OwnerNominated(address newOwner); + event OwnerChanged(address oldOwner, address newOwner); +} diff --git a/src/RewardsDistribution.sol b/src/RewardsDistribution.sol new file mode 100644 index 0000000..dedc5b1 --- /dev/null +++ b/src/RewardsDistribution.sol @@ -0,0 +1,22 @@ +pragma solidity ^0.5.16; + +import "./Owned.sol"; +import "./interfaces/IRewardsDistributionRecipient.sol"; + +contract RewardsDistribution is Owned { + constructor(address _owner) public Owned(_owner) {} + + function() external payable {} + + function distributeRewards(address ktonStakingRewards, uint256 reward) external payable onlyOwner returns (bool) { + require(reward > 0, "Nothing to distribute"); + require( + address(this).balance >= reward, "RewardsDistribution contract does not have enough tokens to distribute" + ); + IRewardsDistributionRecipient(ktonStakingRewards).notifyRewardAmount.value(reward)(); + emit RewardsDistributed(reward); + return true; + } + + event RewardsDistributed(uint256 amount); +} diff --git a/src/RewardsDistributionRecipient.sol b/src/RewardsDistributionRecipient.sol index f145197..3c95ba8 100644 --- a/src/RewardsDistributionRecipient.sol +++ b/src/RewardsDistributionRecipient.sol @@ -2,9 +2,10 @@ pragma solidity ^0.5.16; contract RewardsDistributionRecipient { // "sc/ktnstk" in bytes. - address public constant rewardsDistribution = 0x73632F6b746e73746B0000000000000000000000; + // address public constant rewardsDistribution = 0x73632F6b746e73746B0000000000000000000000; + address public rewardsDistribution; - function notifyRewardAmount(uint256 reward) external; + function notifyRewardAmount() external payable; modifier onlyRewardsDistribution() { require(msg.sender == rewardsDistribution, "Caller is not RewardsDistribution contract"); diff --git a/src/interfaces/IRewardsDistributionRecipient.sol b/src/interfaces/IRewardsDistributionRecipient.sol new file mode 100644 index 0000000..005daf4 --- /dev/null +++ b/src/interfaces/IRewardsDistributionRecipient.sol @@ -0,0 +1,5 @@ +pragma solidity >=0.4.24; + +interface IRewardsDistributionRecipient { + function notifyRewardAmount() external payable; +} From 3af5196b7c2a932da9b92a72170bfc666720d653 Mon Sep 17 00:00:00 2001 From: echo Date: Wed, 21 Feb 2024 16:16:27 +0800 Subject: [PATCH 7/9] deploy on pangolin --- README.md | 6 +-- bin/deploy.sh | 47 ++++++++++++++---- flat/KTONStakingRewards.f.sol | 16 +++++-- flat/RewardsDistribution.f.sol | 71 ++++++++++++++++++++++++++++ src/RewardsDistributionRecipient.sol | 2 - 5 files changed, 122 insertions(+), 20 deletions(-) create mode 100644 flat/RewardsDistribution.f.sol diff --git a/README.md b/README.md index 00e5be2..9cf00f9 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,9 @@ Forked from Staking pool for KTON. ## Addresses -| NetWork | KTONStakingRewards | | -|-----------|--------------------------------------------|-| -| Pangolin | 0x0000000000F9180bB475E0673d7710beC1bc2Cc0 || +| NetWork | KTONStakingRewards | RewardsDistribution | +|-----------|--------------------------------------------|--------------------------------------------| +| Pangolin | 0x0000004ECebC4FCC2B5537Be6f0731Ad49D96D9c | 0x00000049A769D69Fc5E7eB2B45e02Bc1551f741C | ### API diff --git a/bin/deploy.sh b/bin/deploy.sh index 3405063..42207af 100644 --- a/bin/deploy.sh +++ b/bin/deploy.sh @@ -2,18 +2,45 @@ set -eo pipefail +set -x + chain=${1:?} -addr=0x0000004B21061Ce4C13138C41c3ad694500129cc -salt=0x65fd4e09846a2c80c9661aea1c7662ec870ec1814392afcf88b4454be0e1ce17 c3=0x0000000000C76fe1798a428F60b27c6724e03408 deployer=0x0f14341A7f464320319025540E8Fe48Ad0fe5aec -bytecode=0x$(jq -r ".contracts[\"src/KTONStakingRewards.sol\"].KTONStakingRewards.evm.bytecode.object" out/dapp.sol.json) -# salt, creationCode -expect_addr=$(seth call $c3 "deploy(bytes32,bytes)(address)" $salt $bytecode --chain $chain) +deploy() { + local addr=${1:?} + local salt=${2:?} + local bytecode=${3:?} + expect_addr=$(seth call $c3 "deploy(bytes32,bytes)(address)" $salt $bytecode --chain $chain) + + if [[ $(seth --to-checksum-address "${addr}") == $(seth --to-checksum-address "${expect_addr}") ]]; then + (set -x; seth send $c3 "deploy(bytes32,bytes)" $salt $bytecode --chain $chain) + else + echo "Unexpected address." + fi +} + +distribution_addr=0x00000049A769D69Fc5E7eB2B45e02Bc1551f741C +distribution_salt=0x27b58878fc24bfd82636938cacd4c93f4365ddf970f0546fe52a756b7ffe8bf5 +# "sc/ktnstk" in bytes. +# distribution_owner=0x73632F6b746e73746B0000000000000000000000; +distribution_owner=$deployer + +distribution_bytecode=$(jq -r ".contracts[\"src/RewardsDistribution.sol\"].RewardsDistribution.evm.bytecode.object" out/dapp.sol.json) +distribution_args=$(set -x; ethabi encode params \ + -v address "${distribution_owner:2}" +) +distribution_creationCode=0x$distribution_bytecode$distribution_args + +deploy $distribution_addr $distribution_salt $distribution_creationCode + +staker_addr=0x0000004ECebC4FCC2B5537Be6f0731Ad49D96D9c +staker_salt=0xbb005a3084eed043ef17394e9343cb89c5e2ffc02658565e0748279edb9030dc +staker_bytecode=$(jq -r ".contracts[\"src/KTONStakingRewards.sol\"].KTONStakingRewards.evm.bytecode.object" out/dapp.sol.json) +staker_args=$(set -x; ethabi encode params \ + -v address "${distribution_addr:2}" +) +staker_creationCode=0x$staker_bytecode$staker_args -if [[ $(seth --to-checksum-address "${addr}") == $(seth --to-checksum-address "${expect_addr}") ]]; then - (set -x; seth send $c3 "deploy(bytes32,bytes)" $salt $bytecode --chain $chain) -else - echo "Unexpected address." -fi +deploy $staker_addr $staker_salt $staker_creationCode diff --git a/flat/KTONStakingRewards.f.sol b/flat/KTONStakingRewards.f.sol index 2788d17..c4348eb 100644 --- a/flat/KTONStakingRewards.f.sol +++ b/flat/KTONStakingRewards.f.sol @@ -426,10 +426,9 @@ contract ReentrancyGuard { /* pragma solidity ^0.5.16; */ contract RewardsDistributionRecipient { - // "sc/ktnstk" in bytes. - address public constant rewardsDistribution = 0x73632F6b746e73746B0000000000000000000000; + address public rewardsDistribution; - function notifyRewardAmount() external; + function notifyRewardAmount() external payable; modifier onlyRewardsDistribution() { require(msg.sender == rewardsDistribution, "Caller is not RewardsDistribution contract"); @@ -487,7 +486,7 @@ contract KTONStakingRewards is IStakingRewards, RewardsDistributionRecipient, Re IERC20 public constant stakingToken = IERC20(0x0000000000000000000000000000000000000402); uint256 public periodFinish = 0; uint256 public rewardRate = 0; - uint256 public rewardsDuration = 7200; + uint256 public rewardsDuration = 7 days; uint256 public lastUpdateTime; uint256 public rewardPerTokenStored; @@ -497,6 +496,12 @@ contract KTONStakingRewards is IStakingRewards, RewardsDistributionRecipient, Re uint256 private _totalSupply; mapping(address => uint256) private _balances; + /* ========== CONSTRUCTOR ========== */ + + constructor(address _rewardsDistribution) public { + rewardsDistribution = _rewardsDistribution; + } + /* ========== VIEWS ========== */ function totalSupply() external view returns (uint256) { @@ -564,7 +569,8 @@ contract KTONStakingRewards is IStakingRewards, RewardsDistributionRecipient, Re /* ========== RESTRICTED FUNCTIONS ========== */ - function notifyRewardAmount(uint256 reward) external onlyRewardsDistribution updateReward(address(0)) { + function notifyRewardAmount() external payable onlyRewardsDistribution updateReward(address(0)) { + uint256 reward = msg.value; if (block.timestamp >= periodFinish) { rewardRate = reward.div(rewardsDuration); } else { diff --git a/flat/RewardsDistribution.f.sol b/flat/RewardsDistribution.f.sol new file mode 100644 index 0000000..c97c2fa --- /dev/null +++ b/flat/RewardsDistribution.f.sol @@ -0,0 +1,71 @@ +// hevm: flattened sources of src/RewardsDistribution.sol + +pragma solidity >=0.4.24 >=0.5.16 <0.6.0; + +////// src/Owned.sol +/* pragma solidity ^0.5.16; */ + + +// https://github.com/Synthetixio/synthetix/blob/v2.27.2/contracts/Owned.sol +contract Owned { + address public owner; + address public nominatedOwner; + + constructor(address _owner) public { + require(_owner != address(0), "Owner address cannot be 0"); + owner = _owner; + emit OwnerChanged(address(0), _owner); + } + + function nominateNewOwner(address _owner) external onlyOwner { + nominatedOwner = _owner; + emit OwnerNominated(_owner); + } + + function acceptOwnership() external { + require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership"); + emit OwnerChanged(owner, nominatedOwner); + owner = nominatedOwner; + nominatedOwner = address(0); + } + + modifier onlyOwner { + require(msg.sender == owner, "Only the contract owner may perform this action"); + _; + } + + event OwnerNominated(address newOwner); + event OwnerChanged(address oldOwner, address newOwner); +} + +////// src/interfaces/IRewardsDistributionRecipient.sol +/* pragma solidity >=0.4.24; */ + +interface IRewardsDistributionRecipient { + function notifyRewardAmount() external payable; +} + +////// src/RewardsDistribution.sol +/* pragma solidity ^0.5.16; */ + +/* import "./Owned.sol"; */ +/* import "./interfaces/IRewardsDistributionRecipient.sol"; */ + +contract RewardsDistribution is Owned { + constructor(address _owner) public Owned(_owner) {} + + function() external payable {} + + function distributeRewards(address ktonStakingRewards, uint256 reward) external payable onlyOwner returns (bool) { + require(reward > 0, "Nothing to distribute"); + require( + address(this).balance >= reward, "RewardsDistribution contract does not have enough tokens to distribute" + ); + IRewardsDistributionRecipient(ktonStakingRewards).notifyRewardAmount.value(reward)(); + emit RewardsDistributed(reward); + return true; + } + + event RewardsDistributed(uint256 amount); +} + diff --git a/src/RewardsDistributionRecipient.sol b/src/RewardsDistributionRecipient.sol index 3c95ba8..b312107 100644 --- a/src/RewardsDistributionRecipient.sol +++ b/src/RewardsDistributionRecipient.sol @@ -1,8 +1,6 @@ pragma solidity ^0.5.16; contract RewardsDistributionRecipient { - // "sc/ktnstk" in bytes. - // address public constant rewardsDistribution = 0x73632F6b746e73746B0000000000000000000000; address public rewardsDistribution; function notifyRewardAmount() external payable; From 6a6b9b352acdfe066b7c6f12b6cadc99137d1f52 Mon Sep 17 00:00:00 2001 From: echo Date: Wed, 21 Feb 2024 16:16:51 +0800 Subject: [PATCH 8/9] rm debug info --- bin/deploy.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/bin/deploy.sh b/bin/deploy.sh index 42207af..09c6ac7 100644 --- a/bin/deploy.sh +++ b/bin/deploy.sh @@ -2,8 +2,6 @@ set -eo pipefail -set -x - chain=${1:?} c3=0x0000000000C76fe1798a428F60b27c6724e03408 deployer=0x0f14341A7f464320319025540E8Fe48Ad0fe5aec From ae858db8cace2890dfb0644ed82a9cf11b4c28a2 Mon Sep 17 00:00:00 2001 From: echo Date: Wed, 21 Feb 2024 16:27:05 +0800 Subject: [PATCH 9/9] deploy for runtime --- README.md | 2 +- bin/deploy.sh | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 9cf00f9..6a6de02 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Staking pool for KTON. ## Addresses | NetWork | KTONStakingRewards | RewardsDistribution | |-----------|--------------------------------------------|--------------------------------------------| -| Pangolin | 0x0000004ECebC4FCC2B5537Be6f0731Ad49D96D9c | 0x00000049A769D69Fc5E7eB2B45e02Bc1551f741C | +| Pangolin | 0x0000009174453855101ad2D7981E2fC4222B5ad2 | 0x00000012683ac5ff103025368AF1F81Fc115EfF0 | ### API diff --git a/bin/deploy.sh b/bin/deploy.sh index 09c6ac7..8ebbcd6 100644 --- a/bin/deploy.sh +++ b/bin/deploy.sh @@ -19,11 +19,10 @@ deploy() { fi } -distribution_addr=0x00000049A769D69Fc5E7eB2B45e02Bc1551f741C -distribution_salt=0x27b58878fc24bfd82636938cacd4c93f4365ddf970f0546fe52a756b7ffe8bf5 +distribution_addr=0x00000012683ac5ff103025368AF1F81Fc115EfF0 +distribution_salt=0xcad6cb652297b9cce31cc6c6ab19511394175643c4551d0974b9fe5cde811818 # "sc/ktnstk" in bytes. -# distribution_owner=0x73632F6b746e73746B0000000000000000000000; -distribution_owner=$deployer +distribution_owner=0x73632F6b746e73746B0000000000000000000000; distribution_bytecode=$(jq -r ".contracts[\"src/RewardsDistribution.sol\"].RewardsDistribution.evm.bytecode.object" out/dapp.sol.json) distribution_args=$(set -x; ethabi encode params \ @@ -33,8 +32,8 @@ distribution_creationCode=0x$distribution_bytecode$distribution_args deploy $distribution_addr $distribution_salt $distribution_creationCode -staker_addr=0x0000004ECebC4FCC2B5537Be6f0731Ad49D96D9c -staker_salt=0xbb005a3084eed043ef17394e9343cb89c5e2ffc02658565e0748279edb9030dc +staker_addr=0x0000009174453855101ad2D7981E2fC4222B5ad2 +staker_salt=0xa2a87b8f359c9a1951d7639f04b027a94fe687f785b285ad32a91d30ac396666 staker_bytecode=$(jq -r ".contracts[\"src/KTONStakingRewards.sol\"].KTONStakingRewards.evm.bytecode.object" out/dapp.sol.json) staker_args=$(set -x; ethabi encode params \ -v address "${distribution_addr:2}"