-
Notifications
You must be signed in to change notification settings - Fork 578
Expand file tree
/
Copy pathPredicateRouterWrapper.sol
More file actions
89 lines (77 loc) · 2.96 KB
/
PredicateRouterWrapper.sol
File metadata and controls
89 lines (77 loc) · 2.96 KB
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
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.8.0;
/*@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@ HYPERLANE @@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@*/
// ============ Internal Imports ============
import {AbstractPredicateWrapper} from "../libs/AbstractPredicateWrapper.sol";
/**
* @title PredicateRouterWrapper
* @author Abacus Works
* @notice Wraps an existing TokenRouter with Predicate attestation validation.
* Acts as BOTH a user entry point AND a post-dispatch hook.
* @dev Security model:
* 1. User calls transferRemoteWithAttestation() on this wrapper
* 2. Wrapper validates attestation via PredicateClient, sets pendingAttestation = true
* 3. Wrapper calls router.transferRemote()
* 4. Router dispatches message, mailbox calls this contract's postDispatch()
* 5. postDispatch() verifies pendingAttestation == true, then clears it
*
* If someone bypasses wrapper and calls the router directly, postDispatch()
* will revert because pendingAttestation will be false.
*
* Usage:
* 1. Deploy PredicateRouterWrapper pointing to existing warp route
* 2. Set PredicateRouterWrapper as the hook on the warp route: router.setHook(predicateWrapper)
* 3. Optionally aggregate with default hook for IGP using StaticAggregationHook
* 4. Users call predicateWrapper.transferRemoteWithAttestation() instead of router.transferRemote()
*
* @custom:oz-version 4.9.x (uses Ownable without constructor argument)
*/
contract PredicateRouterWrapper is AbstractPredicateWrapper {
// ============ Enums ============
enum TokenType {
Native,
Synthetic,
Collateral
}
// ============ Events ============
/// @notice Emitted when a transfer is authorized via attestation
event TransferAuthorized(
address indexed sender,
uint32 indexed destination,
bytes32 indexed recipient,
uint256 amount,
string uuid
);
// ============ Constructor ============
constructor(
address _warpRoute,
address _registry,
string memory _policyID
) AbstractPredicateWrapper(_warpRoute, _registry, _policyID) {}
// ============ Views ============
function tokenType() public view returns (TokenType) {
if (token == address(0)) return TokenType.Native;
if (token == address(warpRoute)) return TokenType.Synthetic;
return TokenType.Collateral;
}
// ============ Internal Overrides ============
function _emitTransferAuthorized(
address sender,
uint32 destination,
bytes32 recipient,
uint256 amount,
string calldata uuid
) internal override {
emit TransferAuthorized(sender, destination, recipient, amount, uuid);
}
}