tempo_contracts/precompiles/
tip20.rs

1pub use IRolesAuth::{IRolesAuthErrors as RolesAuthError, IRolesAuthEvents as RolesAuthEvent};
2pub use ITIP20::{ITIP20Errors as TIP20Error, ITIP20Events as TIP20Event};
3use alloy::{
4    primitives::{Address, U256},
5    sol,
6};
7
8sol! {
9    #[derive(Debug, PartialEq, Eq)]
10    #[sol(rpc, abi)]
11    interface IRolesAuth {
12        function hasRole(address account, bytes32 role) external view returns (bool);
13        function getRoleAdmin(bytes32 role) external view returns (bytes32);
14        function grantRole(bytes32 role, address account) external;
15        function revokeRole(bytes32 role, address account) external;
16        function renounceRole(bytes32 role) external;
17        function setRoleAdmin(bytes32 role, bytes32 adminRole) external;
18
19        event RoleMembershipUpdated(bytes32 indexed role, address indexed account, address indexed sender, bool hasRole);
20        event RoleAdminUpdated(bytes32 indexed role, bytes32 indexed newAdminRole, address indexed sender);
21
22        error Unauthorized();
23    }
24
25    /// TIP20 token interface providing standard ERC20 functionality with Tempo-specific extensions.
26    ///
27    /// TIP20 tokens extend the ERC20 standard with:
28    /// - Currency denomination support for real-world asset backing
29    /// - Transfer policy enforcement for compliance
30    /// - Supply caps for controlled token issuance
31    /// - Pause/unpause functionality for emergency controls
32    /// - Memo support for transaction context
33    /// The interface supports both standard token operations and administrative functions
34    /// for managing token behavior and compliance requirements.
35    #[derive(Debug, PartialEq, Eq)]
36    #[sol(rpc, abi)]
37    #[allow(clippy::too_many_arguments)]
38    interface ITIP20 {
39        // Standard token functions
40        function name() external view returns (string memory);
41        function symbol() external view returns (string memory);
42        function decimals() external view returns (uint8);
43        function totalSupply() external view returns (uint256);
44        function quoteToken() external view returns (address);
45        function nextQuoteToken() external view returns (address);
46        function balanceOf(address account) external view returns (uint256);
47        function transfer(address to, uint256 amount) external returns (bool);
48        function approve(address spender, uint256 amount) external returns (bool);
49        function allowance(address owner, address spender) external view returns (uint256);
50        function transferFrom(address from, address to, uint256 amount) external returns (bool);
51        function mint(address to, uint256 amount) external;
52        function burn(uint256 amount) external;
53
54        // TIP20 Extension
55        function currency() external view returns (string memory);
56        function supplyCap() external view returns (uint256);
57        function paused() external view returns (bool);
58        function transferPolicyId() external view returns (uint64);
59        function burnBlocked(address from, uint256 amount) external;
60        function mintWithMemo(address to, uint256 amount, bytes32 memo) external;
61        function burnWithMemo(uint256 amount, bytes32 memo) external;
62        function transferWithMemo(address to, uint256 amount, bytes32 memo) external;
63        function transferFromWithMemo(address from, address to, uint256 amount, bytes32 memo) external returns (bool);
64        function feeRecipient() external view returns (address);
65        function setFeeRecipient(address newRecipient) external view returns (address);
66
67        // Admin Functions
68        function changeTransferPolicyId(uint64 newPolicyId) external;
69        function setSupplyCap(uint256 newSupplyCap) external;
70        function pause() external;
71        function unpause() external;
72        function setNextQuoteToken(address newQuoteToken) external;
73        function completeQuoteTokenUpdate() external;
74
75        /// @notice Returns the role identifier for pausing the contract
76        /// @return The pause role identifier
77        function PAUSE_ROLE() external view returns (bytes32);
78
79        /// @notice Returns the role identifier for unpausing the contract
80        /// @return The unpause role identifier
81        function UNPAUSE_ROLE() external view returns (bytes32);
82
83        /// @notice Returns the role identifier for issuing tokens
84        /// @return The issuer role identifier
85        function ISSUER_ROLE() external view returns (bytes32);
86
87        /// @notice Returns the role identifier for burning tokens from blocked accounts
88        /// @return The burn blocked role identifier
89        function BURN_BLOCKED_ROLE() external view returns (bytes32);
90
91        struct RewardStream {
92            address funder;
93            uint64 startTime;
94            uint64 endTime;
95            uint256 ratePerSecondScaled;
96            uint256 amountTotal;
97        }
98
99        struct UserRewardInfo {
100            address rewardRecipient;
101            uint256 rewardPerToken;
102            uint256 rewardBalance;
103        }
104
105        // Reward Functions
106        function startReward(uint256 amount, uint32 secs) external returns (uint64);
107        function setRewardRecipient(address recipient) external;
108        function cancelReward(uint64 id) external returns (uint256);
109        function claimRewards() external returns (uint256);
110        function finalizeStreams(uint64 timestamp) external;
111        function getStream(uint64 id) external view returns (RewardStream memory);
112        function totalRewardPerSecond() external view returns (uint256);
113        function optedInSupply() external view returns (uint128);
114        function nextStreamId() external view returns (uint64);
115        function userRewardInfo(address account) external view returns (UserRewardInfo memory);
116
117        // Events
118        event Transfer(address indexed from, address indexed to, uint256 amount);
119        event Approval(address indexed owner, address indexed spender, uint256 amount);
120        event Mint(address indexed to, uint256 amount);
121        event Burn(address indexed from, uint256 amount);
122        event BurnBlocked(address indexed from, uint256 amount);
123        event TransferWithMemo(address indexed from, address indexed to, uint256 amount, bytes32 indexed memo);
124        event TransferPolicyUpdate(address indexed updater, uint64 indexed newPolicyId);
125        event SupplyCapUpdate(address indexed updater, uint256 indexed newSupplyCap);
126        event PauseStateUpdate(address indexed updater, bool isPaused);
127        event NextQuoteTokenSet(address indexed updater, address indexed nextQuoteToken);
128        event QuoteTokenUpdate(address indexed updater, address indexed newQuoteToken);
129        event RewardScheduled(address indexed funder, uint64 indexed id, uint256 amount, uint32 durationSeconds);
130        event RewardCanceled(address indexed funder, uint64 indexed id, uint256 refund);
131        event RewardRecipientSet(address indexed holder, address indexed recipient);
132        event FeeRecipientUpdated(address indexed updater, address indexed newRecipient);
133
134        // Errors
135        error InsufficientBalance(uint256 available, uint256 required, address token);
136        error InsufficientAllowance();
137        error SupplyCapExceeded();
138        error InvalidSupplyCap();
139        error InvalidPayload();
140        error StringTooLong();
141        error PolicyForbids();
142        error InvalidRecipient();
143        error ContractPaused();
144        error InvalidCurrency();
145        error InvalidQuoteToken();
146        error TransfersDisabled();
147        error InvalidAmount();
148        error NotStreamFunder();
149        error StreamInactive();
150        error NoOptedInSupply();
151        error Unauthorized();
152        error RewardsDisabled();
153        error ScheduledRewardsDisabled();
154        error ProtectedAddress();
155        error InvalidToken();
156    }
157}
158
159impl RolesAuthError {
160    /// Creates an error for unauthorized access.
161    pub const fn unauthorized() -> Self {
162        Self::Unauthorized(IRolesAuth::Unauthorized {})
163    }
164}
165
166impl TIP20Error {
167    /// Creates an error for insufficient token balance.
168    pub const fn insufficient_balance(available: U256, required: U256, token: Address) -> Self {
169        Self::InsufficientBalance(ITIP20::InsufficientBalance {
170            available,
171            required,
172            token,
173        })
174    }
175
176    /// Creates an error for insufficient spending allowance.
177    pub const fn insufficient_allowance() -> Self {
178        Self::InsufficientAllowance(ITIP20::InsufficientAllowance {})
179    }
180
181    /// Creates an error for unauthorized callers
182    pub const fn unauthorized() -> Self {
183        Self::Unauthorized(ITIP20::Unauthorized {})
184    }
185
186    /// Creates an error when minting would set a supply cap that is too large, or invalid.
187    pub const fn invalid_supply_cap() -> Self {
188        Self::InvalidSupplyCap(ITIP20::InvalidSupplyCap {})
189    }
190
191    /// Creates an error when minting would exceed supply cap.
192    pub const fn supply_cap_exceeded() -> Self {
193        Self::SupplyCapExceeded(ITIP20::SupplyCapExceeded {})
194    }
195
196    /// Creates an error for invalid payload data.
197    pub const fn invalid_payload() -> Self {
198        Self::InvalidPayload(ITIP20::InvalidPayload {})
199    }
200
201    /// Creates an error for invalid quote token.
202    pub const fn invalid_quote_token() -> Self {
203        Self::InvalidQuoteToken(ITIP20::InvalidQuoteToken {})
204    }
205
206    /// Creates an error when string parameter exceeds maximum length.
207    pub const fn string_too_long() -> Self {
208        Self::StringTooLong(ITIP20::StringTooLong {})
209    }
210
211    /// Creates an error when transfer is forbidden by policy.
212    pub const fn policy_forbids() -> Self {
213        Self::PolicyForbids(ITIP20::PolicyForbids {})
214    }
215
216    /// Creates an error for invalid recipient address.
217    pub const fn invalid_recipient() -> Self {
218        Self::InvalidRecipient(ITIP20::InvalidRecipient {})
219    }
220
221    /// Creates an error when contract is paused.
222    pub const fn contract_paused() -> Self {
223        Self::ContractPaused(ITIP20::ContractPaused {})
224    }
225
226    /// Creates an error for invalid currency.
227    pub const fn invalid_currency() -> Self {
228        Self::InvalidCurrency(ITIP20::InvalidCurrency {})
229    }
230
231    /// Creates an error for transfers being disabled.
232    pub const fn transfers_disabled() -> Self {
233        Self::TransfersDisabled(ITIP20::TransfersDisabled {})
234    }
235
236    /// Creates an error for invalid amount.
237    pub const fn invalid_amount() -> Self {
238        Self::InvalidAmount(ITIP20::InvalidAmount {})
239    }
240
241    /// Error for when stream does not exist
242    pub const fn stream_inactive() -> Self {
243        Self::StreamInactive(ITIP20::StreamInactive {})
244    }
245
246    /// Error for when msg.sedner is not stream funder
247    pub const fn not_stream_funder() -> Self {
248        Self::NotStreamFunder(ITIP20::NotStreamFunder {})
249    }
250
251    /// Error for when opted in supply is 0
252    pub const fn no_opted_in_supply() -> Self {
253        Self::NoOptedInSupply(ITIP20::NoOptedInSupply {})
254    }
255
256    /// Error for when rewards are disabled
257    pub const fn rewards_disabled() -> Self {
258        Self::RewardsDisabled(ITIP20::RewardsDisabled {})
259    }
260
261    /// Error for when scheduled rewards are disabled post-moderato
262    pub const fn scheduled_rewards_disabled() -> Self {
263        Self::ScheduledRewardsDisabled(ITIP20::ScheduledRewardsDisabled {})
264    }
265
266    /// Error for operations on protected addresses (like burning `FeeManager` tokens)
267    pub const fn protected_address() -> Self {
268        Self::ProtectedAddress(ITIP20::ProtectedAddress {})
269    }
270
271    /// Error when an address is not a valid TIP20 token
272    pub const fn invalid_token() -> Self {
273        Self::InvalidToken(ITIP20::InvalidToken {})
274    }
275}