Skip to content

Instantly share code, notes, and snippets.

@gorbunovperm
Created October 12, 2018 05:51
Show Gist options
  • Save gorbunovperm/baec3a9b533b922c34a32a6a8d4f579f to your computer and use it in GitHub Desktop.
Save gorbunovperm/baec3a9b533b922c34a32a6a8d4f579f to your computer and use it in GitHub Desktop.
Callisto ColdStaking smart contract security audit report

Callisto ColdStaking smart contract security audit report

Summary

This is the report from a security audit performed on Cold-staking by gorbunovperm.

Callisto Cold staking contract.

In scope

  1. ColdStaking.sol

Findings

In total, 4 issues were reported including:

  • 0 high severity issue.

  • 2 medium severity issues.

  • 1 low severity issues.

  • 1 minor observations.

Security issues

1. A staker will lose the deserved reward if he makes an additional deposit before the end of the round.

Severity: medium

Code snippet

Description

Round interval is 27 days. Mike makes deposit to coldstaking and after 53 days he made a staking contract replenishment. In this case he will lose reward for 26 days. Reward is paid only for full periods and after that the time of the staking is reset.

Time of staking start is correctly recalculated here but further the time is reset. This is the same as the lose a reward.

Recommendation

For case if need to get reward when making new deposit to stake do add staker weight(for uncompleted round) to staker amount value.

2. Reward depends on StakingRewardPool value and this is the motivation to manipulate the order of transactions.

Severity: medium

Code snippet

Description

Reward depends on StakingRewardPool value. If one staker will claim his reward, another user with same stake value and staking time but which will call claim function in next transaction will get less reward. This is essential for stakers with big stakes.

Recommendation

Change StakingRewardPool one time at block. Do not change it in claim function.

3. Timestamp may have not right meaning. A round can go faster than 27 days.

Severity: low

Code snippet

Description

The round can go faster than 27 days in case of an increase block generation time to over 25 seconds for a long time.

In case when blocktime is more than 25 seconds the Timestamp will have not "timestamp of the last interaction" value (look at here). This will lead to a distortion of the flow of staking time.

Consider the problem by example:

Block id Block time, sec _seconds variable now Timestamp variable now - Timestamp = Recommendation
start value 1539260000 Mike make a stake.
1200000 35 25 1539260035 1539260025 10
1200001 35 25 1539260070 1539260050 20
1200002 35 25 1539260105 1539260075 30
... ... ... ... ... ... An hour has passed
1200103 35 25 1539263640 1539262600 1040 Passed 1 hour of real time, but the contract "thinks" that 43 minutes have passed.

I don't know whether a continuous change in the block generation time by a value greater than 25 seconds is possible. But if it is possible then the time inside the contract will differ from the real time. What will affect the reward.

4. Stake time not updated after withdrawal.

Severity: minor observation

Code snippet

Description

staker[msg.sender].time is not reset after withdrawal process. Only variable staker[msg.sender].amount is reset.

  1. Result of staker_info function may be misleading because after withdrawal amount will be zero, but time will have stake timestamp value.

  2. This is just a reminder for developers. staker[msg.sender].time variable should always used with staker[msg.sender].amount > 0 condition.

Conclusion

This contract has some issues that should be fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment