Guest User

hot cold wallet

a guest
Dec 27th, 2017
30
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. pragma solidity ^0.4.19;
  2.  
  3. contract Vault {
  4.  
  5. address public hot; // Hot wallet key
  6. address public cold; // Cold wallet key
  7. uint public hot_coins; // Coins for hot wallet
  8. uint public cold_coins; // Coins for cold wallet
  9. uint public coldToHot_delay; // Time delay to move coins from cold to hot wallet
  10. uint public hotToWithdraw_delay; // Time delay to move coins from hot wallet to user
  11. bool public lockdown; // Only cold key can be used
  12. uint public request_counter;
  13. mapping (uint => uint) public requests;
  14. mapping (address => WithdrawalRequest[]) public withdrawals;
  15.  
  16. modifier notLockDown {
  17. require(!lockdown);
  18. _;
  19. }
  20.  
  21. struct WithdrawalRequest {
  22. uint coins;
  23. uint time;
  24. }
  25.  
  26. // Hot address = All actions are time delayed (moving from cold to hot, moving from hot to user)
  27. // Cold address = All actions are instant (moving from cold to hot wallet)
  28. // Cold to Hot Timer = How long it takes to move coins from hot to cold wallet (if authorised by hot wallet)
  29. // Hot to User Timer = How long it takes to move coins from hot wallet to user (if authorised by hot wallet)
  30. function Vault(address _hot, address _cold, uint _coldToHot, uint _hotToWithdraw) public {
  31. hot = _hot;
  32. cold = _cold;
  33. coldToHot_delay = _coldToHot;
  34. hotToWithdraw_delay = _hotToWithdraw;
  35. lockdown = false;
  36. request_counter = block.number;
  37. }
  38.  
  39. // Deposit coins into cold wallet
  40. function deposit() public payable notLockDown {
  41. cold_coins = cold_coins + msg.value;
  42. }
  43.  
  44. // Only hot or cold key can use this function
  45. function requestMoveColdToHot(uint amount) public notLockDown {
  46.  
  47. // Can we perform the move?
  48. if(cold_coins >= amount) {
  49.  
  50. // Only hot or cold wallet can authorise moving these coins
  51. // Hot = time delay
  52. // Cold = instant
  53. if(msg.sender == hot) {
  54.  
  55. // Update cold balance!
  56. cold_coins = cold_coins - amount;
  57.  
  58. // Need to enforce time delay (block.number + delay) and update coins that can be released in this future block
  59. requests[block.number + coldToHot_delay] = requests[block.number + coldToHot_delay] + amount;
  60.  
  61. } else if(msg.sender == cold) {
  62. // No time delay for cold wallet!
  63. cold_coins = cold_coins - amount;
  64. hot_coins = hot_coins + amount;
  65. }
  66. }
  67. }
  68.  
  69. // Confirm moving coins from cold to hot up to the previous block
  70. function completeMoveColdToHot() public notLockDown {
  71.  
  72. // Only hot or cold wallet are authorised to update counter
  73. if(msg.sender == cold || msg.sender == hot) {
  74.  
  75. // Go through each request that is now *valid* and update hot wallet balance
  76. for(uint i=request_counter; i<=block.number; i++) {
  77.  
  78. // Update hot coins (and deduct from requests).
  79. uint amount = requests[i];
  80. requests[i] = 0;
  81. hot_coins = hot_coins + amount;
  82.  
  83. // TODO: Chek remaining gas - stop if we are getting too low.
  84. }
  85.  
  86. // Last number we checked was block.number
  87. // TODO: Update when dealing with remaining gas issue
  88. request_counter = block.number;
  89. }
  90. }
  91.  
  92. // Hot wallet can authorise sending coins to a user (a time delay is incorporated)
  93. function authoriseWithdraw(address user, uint amount) public notLockDown {
  94.  
  95. // We have enough coins for request; and only the hot wallet can call this function
  96. if(hot_coins >= amount && msg.sender == hot) {
  97.  
  98. // deduct balance
  99. hot_coins = hot_coins - amount;
  100.  
  101. // Create request for the requested coins + the delay before it is allowed
  102. WithdrawalRequest memory withdraw = WithdrawalRequest(amount, block.number + hotToWithdraw_delay);
  103.  
  104. // Push new withdraw request for the specified user
  105. withdrawals[user].push(withdraw);
  106. }
  107. }
  108.  
  109. // Users can withdraw their coins
  110. function withdraw() public notLockDown {
  111.  
  112. uint towithdraw = 0;
  113.  
  114. // Check if there are coins to send this user
  115. for(uint i=0; i<withdrawals[msg.sender].length; i++) {
  116.  
  117. // Is this withdrawal now valid?
  118. if(withdrawals[msg.sender][i].time <= block.number) {
  119.  
  120. // Awesome! Record coins to send (and empty list)
  121. uint amount = withdrawals[msg.sender][i].coins;
  122. withdrawals[msg.sender][i].coins = 0;
  123. withdrawals[msg.sender][i].time = 0;
  124. towithdraw = towithdraw + amount;
  125. }
  126. }
  127.  
  128. // Send user their coins!
  129. msg.sender.transfer(towithdraw);
  130. }
  131.  
  132. // Lock down contract!
  133. function lockdown() public {
  134. if(msg.sender == hot || msg.sender == cold) {
  135. lockdown = true;
  136. }
  137. }
  138.  
  139. // Cold wallet can authorise moving coins anywhere (i.e. our escape hatch)
  140. function withdrawFromLockDown(address newowner) public {
  141.  
  142. // Must be cold wallet and in lock down mode
  143. require(msg.sender == cold);
  144. require(lockdown);
  145.  
  146. // Send all coins to the new owner (as dictated by the cold wallet)
  147. newowner.transfer(this.balance);
  148. }
  149. }
RAW Paste Data