-
Notifications
You must be signed in to change notification settings - Fork 77
/
AtomicBridgeCounterpartyMOVE.sol
100 lines (80 loc) · 3.77 KB
/
AtomicBridgeCounterpartyMOVE.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {IAtomicBridgeCounterpartyMOVE} from "./IAtomicBridgeCounterpartyMOVE.sol";
import {AtomicBridgeInitiatorMOVE} from "./AtomicBridgeInitiatorMOVE.sol";
import {RateLimiter} from "./RateLimiter.sol";
contract AtomicBridgeCounterpartyMOVE is IAtomicBridgeCounterpartyMOVE, OwnableUpgradeable {
enum MessageState {
PENDING,
COMPLETED,
REFUNDED
}
struct BridgeTransferDetails {
bytes32 originator;
address recipient;
uint256 amount;
bytes32 hashLock;
uint256 timeLock;
MessageState state;
}
AtomicBridgeInitiatorMOVE public atomicBridgeInitiatorMOVE;
RateLimiter public rateLimiter;
mapping(bytes32 => BridgeTransferDetails) public bridgeTransfers;
// Configurable time lock duration
uint256 public counterpartyTimeLockDuration;
function initialize(address _atomicBridgeInitiator, address owner, uint256 _timeLockDuration) public initializer {
if (_atomicBridgeInitiator == address(0)) revert ZeroAddress();
atomicBridgeInitiatorMOVE = AtomicBridgeInitiatorMOVE(_atomicBridgeInitiator);
__Ownable_init(owner);
// Set the configurable time lock duration
counterpartyTimeLockDuration = _timeLockDuration;
}
function setAtomicBridgeInitiator(address _atomicBridgeInitiator) external onlyOwner {
if (_atomicBridgeInitiator == address(0)) revert ZeroAddress();
atomicBridgeInitiatorMOVE = AtomicBridgeInitiatorMOVE(_atomicBridgeInitiator);
}
function setTimeLockDuration(uint256 _timeLockDuration) external onlyOwner {
counterpartyTimeLockDuration = _timeLockDuration;
}
function setRateLimiter(address _rateLimiter) external onlyOwner {
if (_rateLimiter == address(0)) revert ZeroAddress();
rateLimiter = RateLimiter(_rateLimiter);
}
function lockBridgeTransfer(
bytes32 originator,
bytes32 bridgeTransferId,
bytes32 hashLock,
address recipient,
uint256 amount
) external onlyOwner {
if (amount == 0) revert ZeroAmount();
// The time lock is now based on the configurable duration
uint256 timeLock = block.timestamp + counterpartyTimeLockDuration;
bridgeTransfers[bridgeTransferId] = BridgeTransferDetails({
recipient: recipient,
originator: originator,
amount: amount,
hashLock: hashLock,
timeLock: timeLock,
state: MessageState.PENDING
});
emit BridgeTransferLocked(bridgeTransferId, recipient, amount, hashLock, counterpartyTimeLockDuration);
}
function completeBridgeTransfer(bytes32 bridgeTransferId, bytes32 preImage) external {
BridgeTransferDetails storage details = bridgeTransfers[bridgeTransferId];
if (details.state != MessageState.PENDING) revert BridgeTransferStateNotPending();
bytes32 computedHash = keccak256(abi.encodePacked(preImage));
if (computedHash != details.hashLock) revert InvalidSecret();
if (block.timestamp > details.timeLock) revert TimeLockExpired();
details.state = MessageState.COMPLETED;
emit BridgeTransferCompleted(bridgeTransferId, preImage);
}
function abortBridgeTransfer(bytes32 bridgeTransferId) external onlyOwner {
BridgeTransferDetails storage details = bridgeTransfers[bridgeTransferId];
if (details.state != MessageState.PENDING) revert BridgeTransferStateNotPending();
if (block.timestamp <= details.timeLock) revert TimeLockNotExpired();
details.state = MessageState.REFUNDED;
emit BridgeTransferAborted(bridgeTransferId);
}
}