Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Audit fix #5

Merged
merged 9 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ Forked from
Staking pool for KTON.

## Addresses
| NetWork | KTON Staker Deployment Address |
|-----------|--------------------------------------------|
| Pangolin | 0x0000003f5bA7A4EA41655aDbC89c2A668d449128 |
| NetWork | KTONStakingRewards | RewardsDistribution |
|-----------|--------------------------------------------|--------------------------------------------|
| Pangolin | 0x0000009174453855101ad2D7981E2fC4222B5ad2 | 0x00000012683ac5ff103025368AF1F81Fc115EfF0 |

### API

Expand Down
50 changes: 33 additions & 17 deletions bin/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,41 @@
set -eo pipefail

chain=${1:?}
addr=0x0000000000F9180bB475E0673d7710beC1bc2Cc0
salt=0xfa22cbd0171eac53025c57496561ca39c3e6a4e8affe2848552ec79f85513fae
c3=0x0000000000C76fe1798a428F60b27c6724e03408
deployer=0x0f14341A7f464320319025540E8Fe48Ad0fe5aec

KTON=0x0000000000000000000000000000000000000402
STAKING_PALLET=0x6d6f646c64612f74727372790000000000000000
deploy() {
local addr=${1:?}
local salt=${2:?}
local bytecode=${3:?}
expect_addr=$(seth call $c3 "deploy(bytes32,bytes)(address)" $salt $bytecode --chain $chain)

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}"
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=0x00000012683ac5ff103025368AF1F81Fc115EfF0
distribution_salt=0xcad6cb652297b9cce31cc6c6ab19511394175643c4551d0974b9fe5cde811818
# "sc/ktnstk" in bytes.
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 \
-v address "${distribution_owner:2}"
)
distribution_creationCode=0x$distribution_bytecode$distribution_args

deploy $distribution_addr $distribution_salt $distribution_creationCode

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}"
)
creationCode=0x$bytecode$args
# salt, creationCode
expect_addr=$(seth call $c3 "deploy(bytes32,bytes)(address)" $salt $creationCode --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)
else
echo "Unexpected address."
fi
staker_creationCode=0x$staker_bytecode$staker_args

deploy $staker_addr $staker_salt $staker_creationCode
8 changes: 3 additions & 5 deletions flat/KTONStakingRewards.f.sol
Original file line number Diff line number Diff line change
Expand Up @@ -483,10 +483,10 @@ 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;
uint256 public rewardsDuration = 7 days;
uint256 public lastUpdateTime;
uint256 public rewardPerTokenStored;

Expand All @@ -498,8 +498,7 @@ contract KTONStakingRewards is IStakingRewards, RewardsDistributionRecipient, Re

/* ========== CONSTRUCTOR ========== */

constructor(address _rewardsDistribution, address _stakingToken) public {
stakingToken = IERC20(_stakingToken);
constructor(address _rewardsDistribution) public {
rewardsDistribution = _rewardsDistribution;
}

Expand Down Expand Up @@ -572,7 +571,6 @@ contract KTONStakingRewards is IStakingRewards, RewardsDistributionRecipient, Re

function notifyRewardAmount() external payable onlyRewardsDistribution updateReward(address(0)) {
uint256 reward = msg.value;
require(reward >= rewardsDuration, "Provided reward too low");
if (block.timestamp >= periodFinish) {
rewardRate = reward.div(rewardsDuration);
} else {
Expand Down
71 changes: 71 additions & 0 deletions flat/RewardsDistribution.f.sol
Original file line number Diff line number Diff line change
@@ -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);
}

8 changes: 3 additions & 5 deletions src/KTONStakingRewards.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ 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;
uint256 public rewardsDuration = 7 days;
uint256 public lastUpdateTime;
uint256 public rewardPerTokenStored;

Expand All @@ -31,8 +31,7 @@ contract KTONStakingRewards is IStakingRewards, RewardsDistributionRecipient, Re

/* ========== CONSTRUCTOR ========== */

constructor(address _rewardsDistribution, address _stakingToken) public {
stakingToken = IERC20(_stakingToken);
constructor(address _rewardsDistribution) public {
rewardsDistribution = _rewardsDistribution;
}

Expand Down Expand Up @@ -105,7 +104,6 @@ contract KTONStakingRewards is IStakingRewards, RewardsDistributionRecipient, Re

function notifyRewardAmount() external payable onlyRewardsDistribution updateReward(address(0)) {
uint256 reward = msg.value;
require(reward >= rewardsDuration, "Provided reward too low");
if (block.timestamp >= periodFinish) {
rewardRate = reward.div(rewardsDuration);
} else {
Expand Down
34 changes: 34 additions & 0 deletions src/Owned.sol
Original file line number Diff line number Diff line change
@@ -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);
}
22 changes: 22 additions & 0 deletions src/RewardsDistribution.sol
Original file line number Diff line number Diff line change
@@ -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);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add ktonStakingRewards

return true;
}

event RewardsDistributed(uint256 amount);
}
5 changes: 5 additions & 0 deletions src/interfaces/IRewardsDistributionRecipient.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pragma solidity >=0.4.24;

interface IRewardsDistributionRecipient {
function notifyRewardAmount() external payable;
}
Loading