Created
January 26, 2022 16:48
-
-
Save janoschp/d7de82d6d5dcb72162ef6b65f43ddf9e to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.8.11+commit.d7f03943.js&optimize=false&runs=200&gist=
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//SPDX-License-Identifier: MIT | |
pragma solidity >=0.7.0 <0.9.0; | |
contract CalculateHash { | |
function calculateHash(uint key) external pure returns (bytes32) { | |
return keccak256(abi.encode(key)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//SPDX-License-Identifier: MIT | |
pragma solidity >=0.7.0 <0.9.0; | |
interface HTLStore { | |
// A Deposited event should be emitted after ether has been successfully | |
// deposited to the store. | |
event Deposited(address benefactor, bytes32 lock, uint amount, uint timeout); | |
// A Claimed event should be emitted after deposited ether has been | |
// successfully claimed from the store. | |
event Claimed(address beneficiary, bytes32 lock, uint key, uint amount); | |
// A Recovered event should be emitted after ether has been recovered by the | |
// initial benefactor. | |
event Recovered(address benefactor, bytes32 lock, uint amount); | |
// deposit should add the sent ether to the amount stored for the lock. The | |
// claim period timeout should be reset to now + duration. | |
function deposit(bytes32 lock, uint duration) external payable; | |
// claim should allow a holder of the correct pre-image key to withdraw the | |
// ether stored for the lock = keccak256(key) within the claim period. | |
function claim(uint key) external; | |
// recover should allow the initial depositor to recover the ether stored | |
// for the lock after the claim period has ended. | |
function recover(bytes32 lock) external; | |
} | |
struct DepositStruct { | |
address depositor; | |
bytes32 lock; | |
uint amount; | |
uint timeout; | |
bool claimedOrRecovered; | |
} | |
contract HTLStoreImplementation is HTLStore { | |
mapping(bytes32 => DepositStruct) lockToDepositMap; | |
// deposit should add the sent ether to the amount stored for the lock. The | |
// claim period timeout should be reset to now + duration. | |
function deposit(bytes32 lock, uint duration) override external payable { | |
DepositStruct memory currentDeposit = lockToDepositMap[lock]; | |
require(!currentDeposit.claimedOrRecovered, "This deposit has already been claimed or recovered!"); | |
require(msg.value > 0, "Please add some ether first!"); | |
require(duration > 0, "The timeout has to be larger than 0!"); | |
// Check if it is already in deposits and update the deposit: | |
if (currentDeposit.lock == lock) { | |
require(currentDeposit.depositor == msg.sender, "You are not the original depositor of this deposit!"); | |
uint256 depositedAmount = msg.value; | |
uint256 newAmount = currentDeposit.amount + depositedAmount; | |
uint256 newTimeout = block.timestamp + duration; | |
currentDeposit.amount = newAmount; | |
currentDeposit.timeout = newTimeout; | |
lockToDepositMap[lock] = currentDeposit; | |
emit Deposited(msg.sender, lock, depositedAmount, newTimeout); | |
return; | |
} | |
//otherwise add a new one: | |
uint256 timeout = block.timestamp + duration; | |
lockToDepositMap[lock] = DepositStruct(msg.sender, lock, msg.value, timeout, false); | |
emit Deposited(msg.sender, lock, msg.value, timeout); | |
} | |
// claim should allow a holder of the correct pre-image key to withdraw the | |
// ether stored for the lock = keccak256(key) within the claim period. | |
function claim(uint key) override external { | |
bytes32 lock = keccak256(abi.encode(key)); | |
DepositStruct memory currentDeposit = lockToDepositMap[lock]; | |
require(currentDeposit.lock == lock, "Couldn't find a deposit with that key!"); | |
require(currentDeposit.depositor != msg.sender, "You can't claim your own deposit!"); | |
require(!currentDeposit.claimedOrRecovered, "Deposit has already been claimed or recovered!"); | |
require(currentDeposit.amount > 0, "There no ether in this deposit!"); | |
require(block.timestamp <= currentDeposit.timeout, "Timeout is over!"); | |
currentDeposit.claimedOrRecovered = true; | |
lockToDepositMap[lock] = currentDeposit; | |
emit Claimed(msg.sender, currentDeposit.lock, key, currentDeposit.amount); | |
payable(msg.sender).transfer(currentDeposit.amount); | |
} | |
// recover should allow the initial depositor to recover the ether stored | |
// for the lock after the claim period has ended. | |
function recover(bytes32 lock) override external { | |
DepositStruct memory currentDeposit = lockToDepositMap[lock]; | |
require(currentDeposit.lock == lock, "Couldn't find a deposit with that lock!"); | |
require(currentDeposit.depositor == msg.sender, "You are not the original depositor of this deposit!"); | |
require(!currentDeposit.claimedOrRecovered, "Deposit has already been claimed or recovered!"); | |
require(currentDeposit.amount > 0, "There is no ether in the deposit!"); | |
require(block.timestamp > currentDeposit.timeout, "Timeout is not over yet!"); | |
currentDeposit.claimedOrRecovered = true; | |
lockToDepositMap[lock] = currentDeposit; | |
emit Recovered(msg.sender, lock, currentDeposit.amount); | |
payable(msg.sender).transfer(currentDeposit.amount); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment