Created
March 24, 2023 14:34
-
-
Save ankitchiplunkar/d7d6943dd6284ed9eaabbcd0cee75d75 to your computer and use it in GitHub Desktop.
Escrow contract for Optimistic relay v2
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
contract Escrow { | |
event Payment( | |
address builder, | |
address feeRecipient, | |
uint256 amount, | |
uint256 nonce, | |
uint256 expiry, | |
bytes32 blockhash | |
); | |
struct Account { | |
uint256 timelock; | |
uint256 balance; | |
uint256 nonce; | |
} | |
mapping(address => Account) public accounts; | |
address public immutable admin; | |
uint256 public immutable timelockDuration; | |
constructor(address a, uint256 t) { | |
admin = a; | |
timelockDuration = t; | |
} | |
// builder deposits eth into their account | |
receive() external payable { | |
accounts[msg.sender].balance += msg.value; | |
} | |
// escrow executes payment | |
function pay( | |
address feeRecipient, | |
uint256 amount, | |
uint256 nonce, | |
uint256 blockNumber, | |
bytes32 blockHash, | |
bytes memory permission | |
) public { | |
// Checks | |
bytes32 message = keccak256(abi.encodePacked(feeRecipient, amount, nonce, blockNumber, blockHash)); | |
address builder = ecrecover(message, permission); | |
require(nonce = accounts[builder].nonce + 1, "Builder Nonce does not match"); | |
require(blockhash(blockNumber) == blockHash, "Blockhash does not match"); | |
// Effects | |
accounts[builder].nonce = nonce + 1; | |
accounts[builder].balance -= amount; | |
// Payment | |
payable(feeRecipient).transfer(amount); | |
emit Payment(builder, feeRecipient, amount, nonce, blockNumber, blockhash); | |
} | |
// builder requests exit | |
function requestExit() public { | |
require(accounts[msg.sender].timelock == 0); | |
accounts[msg.sender].timelock = block.number + timelockDuration; | |
} | |
// builder confirms exit | |
function confirmExit() public { | |
Account memory account = accounts[msg.sender]; | |
require(account.timelock != 0 && block.number >= account.timelock); | |
delete accounts[msg.sender]; | |
payable(msg.sender).transfer(account.balance); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment