Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yuriy77k/0074bd128bb29b601702e080c95b1fa4 to your computer and use it in GitHub Desktop.
Save yuriy77k/0074bd128bb29b601702e080c95b1fa4 to your computer and use it in GitHub Desktop.
Callisto ColdStaking smart contract security audit report

Callisto ColdStaking smart contract security audit report


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

Callisto Cold staking contract.

In scope

  1. ColdStaking.sol


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


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.


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


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.


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


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


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.


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