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 `IdentityNames` claims it, and
3//! refundable to each deposit's `refundTo` until then. `deposit` takes
4//! `keccak256(normalized handle)`, from `IdentityNames.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 names_) 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            function names() external view returns (address);
42            /// The EIP-7528 native-token address, `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`.
43            function NATIVE() external view returns (address);
44
45            function owner() external view returns (address);
46            function pendingOwner() external view returns (address);
47            function transferOwnership(address newOwner) external;
48            function acceptOwnership() external;
49            /// Always reverts `RenounceDisabled`.
50            function renounceOwnership() external pure;
51
52            /// Value escrowed for a node nobody holds, booked under `refundTo`
53            /// in `round`, which the next `Claimed` closes.
54            event Deposited(
55                bytes32 indexed handleNode,
56                address indexed token,
57                address indexed refundTo,
58                address depositor,
59                bytes32 platformId,
60                uint256 round,
61                uint256 amount
62            );
63            /// A deposit paid straight to the node's holder; `received` is
64            /// what the holder gained.
65            event Forwarded(
66                bytes32 indexed handleNode,
67                address indexed token,
68                address indexed depositor,
69                address holder,
70                bytes32 platformId,
71                uint256 amount,
72                uint256 received
73            );
74            /// `released` (here and in `Refunded`) left the books; `received`
75            /// is what `recipient` gained. `round` is the one this claim closed.
76            event Claimed(
77                bytes32 indexed handleNode,
78                address indexed token,
79                address indexed claimer,
80                address recipient,
81                uint256 round,
82                uint256 released,
83                uint256 received
84            );
85            event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
86            event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
87            event Refunded(
88                bytes32 indexed handleNode,
89                address indexed token,
90                address indexed refundTo,
91                address recipient,
92                uint256 round,
93                uint256 released,
94                uint256 received
95            );
96
97            error ZeroAmount();
98            /// The caller holds the node it is paying.
99            error PayingYourself(address holder);
100            error ValueMismatch(uint256 expected, uint256 provided);
101            error NothingHeld(bytes32 handleNode);
102            /// The caller is not the node's holder.
103            error NotTheHolder(address holder, address caller);
104            /// Nothing refundable is booked under `refundTo`.
105            error NothingToRefund(bytes32 handleNode, address token, address refundTo);
106            /// `refundTo` is zero or the escrow: nobody could refund.
107            error BadRefundTo(address refundTo);
108            error BadRecipient(address recipient);
109            /// Nobody holds the node and nothing new can bind on the platform.
110            error PlatformAcceptsNoBindings(bytes32 platformId);
111            error NativeTransferFailed(address recipient, uint256 amount);
112            /// A payout took more of the escrow's balance than it booked.
113            error OverDebited(address token, uint256 booked, uint256 debited);
114            error NoNames();
115            /// `initialize`: the naming contract does not answer `selector`.
116            error NamesLacks(address names, bytes4 selector);
117            error RenounceDisabled();
118            error OwnableUnauthorizedAccount(address account);
119            error OwnableInvalidOwner(address owner);
120            /// A deposit, claim or refund was entered again from inside one.
121            error ReentrancyGuardReentrantCall();
122            /// The token answered `false` to a transfer.
123            error SafeERC20FailedOperation(address token);
124        }
125    }
126}
127
128pub use escrow_inner::HandleEscrow;
129
130#[cfg(test)]
131mod tests {
132    use super::escrow_inner::HandleEscrow;
133    use crate::bindings::drift::assert_binding_matches_artifact;
134
135    /// Inherited upgrade and initializer ABI, left to `proxy::IUUPSUpgradeable`.
136    const OMITTED: &[&str] = &[
137        "error AddressEmptyCode(address)",
138        "error ERC1967InvalidImplementation(address)",
139        "error ERC1967NonPayable()",
140        "error FailedCall()",
141        "error InvalidInitialization()",
142        "error NotInitializing()",
143        "error UUPSUnauthorizedCallContext()",
144        "error UUPSUnsupportedProxiableUUID(bytes32)",
145        "event Initialized(uint64)",
146        "event Upgraded(address)",
147        "function UPGRADE_INTERFACE_VERSION()",
148        "function proxiableUUID()",
149        "function upgradeToAndCall(address,bytes)",
150    ];
151
152    #[test]
153    fn the_binding_matches_the_artifact_abi() {
154        assert_binding_matches_artifact(
155            "HandleEscrow",
156            "HandleEscrow",
157            &HandleEscrow::abi::contract(),
158            OMITTED,
159        );
160    }
161}