Skip to main content

libid_contracts/bindings/
escrow.rs

1//! Bindings for the handle escrow (`solidity/contracts/escrow/`): value held
2//! against a handle node until its holder in `IdentityRegistry` claims it, and
3//! refundable to each deposit's `refundTo` until then. `deposit` takes
4//! `keccak256(normalized handle)`, from `IdentityRegistry.handleHashOf` or
5//! computed locally.
6
7/// Bindings for `escrow/HandleEscrow.sol`.
8#[allow(clippy::too_many_arguments, unused_attributes)]
9mod escrow_inner {
10    use alloy::sol;
11
12    sol! {
13        #[sol(rpc, abi)]
14        interface HandleEscrow {
15            function initialize(address owner_, address registry_) external;
16
17            /// Pay a handle by its hash. A held node is paid straight through
18            /// (`Forwarded`); otherwise the value is escrowed (`Deposited`) and
19            /// `refundTo` can `refund` it until the holder claims. An unchecked
20            /// wrong hash funds a slot only `refund` recovers.
21            function deposit(
22                bytes32 platformId,
23                bytes32 handleHash,
24                address token,
25                uint256 amount,
26                address refundTo
27            ) external payable;
28
29            /// Take everything held for a node in each of `tokens`; holder
30            /// only. Tokens with nothing held are skipped; reverts
31            /// `NothingHeld` when none paid.
32            function claim(bytes32 handleNode, address[] calldata tokens, address recipient) external;
33
34            /// Take back the caller's contribution to a node in the current
35            /// round, until the holder claims.
36            function refund(bytes32 handleNode, address token, address recipient) external;
37
38            function escrowed(bytes32 handleNode, address token) external view returns (uint256);
39            /// What `refund` would pay `refundTo` now.
40            function refundable(bytes32 handleNode, address token, address refundTo) external view returns (uint256);
41            /// The identity registry the escrow resolves through.
42            function registry() external view returns (address);
43            /// The EIP-7528 native-token address, `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`.
44            function NATIVE() external view returns (address);
45
46            function owner() external view returns (address);
47            function pendingOwner() external view returns (address);
48            function transferOwnership(address newOwner) external;
49            function acceptOwnership() external;
50            /// Always reverts `RenounceDisabled`.
51            function renounceOwnership() external pure;
52
53            /// Value escrowed for a node nobody holds, booked under `refundTo`
54            /// in `round`, which the next `Claimed` closes.
55            event Deposited(
56                bytes32 indexed handleNode,
57                address indexed token,
58                address indexed refundTo,
59                address depositor,
60                bytes32 platformId,
61                uint256 round,
62                uint256 amount
63            );
64            /// A deposit paid straight to the node's holder; `received` is
65            /// what the holder gained.
66            event Forwarded(
67                bytes32 indexed handleNode,
68                address indexed token,
69                address indexed depositor,
70                address holder,
71                bytes32 platformId,
72                uint256 amount,
73                uint256 received
74            );
75            /// `released` (here and in `Refunded`) left the books; `received`
76            /// is what `recipient` gained. `round` is the one this claim closed.
77            event Claimed(
78                bytes32 indexed handleNode,
79                address indexed token,
80                address indexed claimer,
81                address recipient,
82                uint256 round,
83                uint256 released,
84                uint256 received
85            );
86            event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
87            event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
88            event Refunded(
89                bytes32 indexed handleNode,
90                address indexed token,
91                address indexed refundTo,
92                address recipient,
93                uint256 round,
94                uint256 released,
95                uint256 received
96            );
97
98            error ZeroAmount();
99            /// The caller holds the node it is paying.
100            error PayingYourself(address holder);
101            error ValueMismatch(uint256 expected, uint256 provided);
102            error NothingHeld(bytes32 handleNode);
103            /// The caller is not the node's holder.
104            error NotTheHolder(address holder, address caller);
105            /// Nothing refundable is booked under `refundTo`.
106            error NothingToRefund(bytes32 handleNode, address token, address refundTo);
107            /// `refundTo` is zero or the escrow: nobody could refund.
108            error BadRefundTo(address refundTo);
109            error BadRecipient(address recipient);
110            /// Nobody holds the node and nothing new can bind on the platform.
111            error PlatformAcceptsNoBindings(bytes32 platformId);
112            error NativeTransferFailed(address recipient, uint256 amount);
113            /// A payout took more of the escrow's balance than it booked.
114            error OverDebited(address token, uint256 booked, uint256 debited);
115            error NoRegistry();
116            /// `initialize`: the registry does not answer `selector`.
117            error RegistryLacks(address registry, bytes4 selector);
118            error RenounceDisabled();
119            error OwnableUnauthorizedAccount(address account);
120            error OwnableInvalidOwner(address owner);
121            /// A deposit, claim or refund was entered again from inside one.
122            error ReentrancyGuardReentrantCall();
123            /// The token answered `false` to a transfer.
124            error SafeERC20FailedOperation(address token);
125        }
126    }
127}
128
129pub use escrow_inner::HandleEscrow;
130
131#[cfg(test)]
132mod tests {
133    use super::escrow_inner::HandleEscrow;
134    use crate::bindings::drift::assert_binding_matches_artifact;
135
136    /// Inherited upgrade and initializer ABI, left to `proxy::IUUPSUpgradeable`.
137    const OMITTED: &[&str] = &[
138        "error AddressEmptyCode(address)",
139        "error ERC1967InvalidImplementation(address)",
140        "error ERC1967NonPayable()",
141        "error FailedCall()",
142        "error InvalidInitialization()",
143        "error NotInitializing()",
144        "error UUPSUnauthorizedCallContext()",
145        "error UUPSUnsupportedProxiableUUID(bytes32)",
146        "event Initialized(uint64)",
147        "event Upgraded(address)",
148        "function UPGRADE_INTERFACE_VERSION()",
149        "function proxiableUUID()",
150        "function upgradeToAndCall(address,bytes)",
151    ];
152
153    #[test]
154    fn the_binding_matches_the_artifact_abi() {
155        assert_binding_matches_artifact(
156            "HandleEscrow",
157            "HandleEscrow",
158            &HandleEscrow::abi::contract(),
159            OMITTED,
160        );
161    }
162}