diff --git a/README.md b/README.md index 4123e30..f1138d5 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,6 @@ src │ ├── IStablecoinDEX.sol: Stablecoin DEX | Docs | Implementation │ ├── ITempoStreamChannel.sol: Streaming payment channel escrow (concept) | Implementation │ ├── ITIP20Factory.sol: TIP-20: Factory Contract | Docs | Implementation -│ ├── ITIP20RewardsRegistry.sol: TIP-20: Reward Distribution | Docs | Implementation │ ├── ITIP20RolesAuth.sol: TIP-20: Roles & Permissions | Docs | Implementation │ ├── ITIP20.sol: TIP-20: Core Token Standard | Docs | Implementation │ ├── ITIP403Registry.sol: TIP-403: Policy Registry System | Docs | Implementation diff --git a/src/StdPrecompiles.sol b/src/StdPrecompiles.sol index 513b6c5..344f88f 100644 --- a/src/StdPrecompiles.sol +++ b/src/StdPrecompiles.sol @@ -7,7 +7,6 @@ import {IFeeManager} from "./interfaces/IFeeManager.sol"; import {ISignatureVerifier} from "./interfaces/ISignatureVerifier.sol"; import {ITIP403Registry} from "./interfaces/ITIP403Registry.sol"; import {ITIP20Factory} from "./interfaces/ITIP20Factory.sol"; -import {ITIP20RewardsRegistry} from "./interfaces/ITIP20RewardsRegistry.sol"; import {IStablecoinDEX} from "./interfaces/IStablecoinDEX.sol"; import {IValidatorConfig} from "./interfaces/IValidatorConfig.sol"; import {IValidatorConfigV2} from "./interfaces/IValidatorConfigV2.sol"; @@ -32,8 +31,6 @@ library StdPrecompiles { IFeeManager internal constant TIP_FEE_MANAGER = IFeeManager(TIP_FEE_MANAGER_ADDRESS); ITIP403Registry internal constant TIP403_REGISTRY = ITIP403Registry(TIP403_REGISTRY_ADDRESS); ITIP20Factory internal constant TIP20_FACTORY = ITIP20Factory(TIP20_FACTORY_ADDRESS); - ITIP20RewardsRegistry internal constant TIP20_REWARDS_REGISTRY = - ITIP20RewardsRegistry(TIP20_REWARDS_REGISTRY_ADDRESS); IStablecoinDEX internal constant STABLECOIN_DEX = IStablecoinDEX(STABLECOIN_DEX_ADDRESS); INonce internal constant NONCE_PRECOMPILE = INonce(NONCE_ADDRESS); IValidatorConfig internal constant VALIDATOR_CONFIG = IValidatorConfig(VALIDATOR_CONFIG_ADDRESS); diff --git a/src/interfaces/IFeeAMM.sol b/src/interfaces/IFeeAMM.sol index 2658ef6..73b3bb5 100644 --- a/src/interfaces/IFeeAMM.sol +++ b/src/interfaces/IFeeAMM.sol @@ -2,14 +2,13 @@ pragma solidity >=0.8.13 <0.9.0; interface IFeeAMM { + error DivisionByZero(); error IdenticalAddresses(); + error InvalidAmount(); + error InvalidSwapCalculation(); error InvalidToken(); error InsufficientLiquidity(); error InsufficientReserves(); - error InvalidAmount(); - error DivisionByZero(); - error InvalidSwapCalculation(); - error InvalidCurrency(); event Burn( address indexed sender, diff --git a/src/interfaces/IFeeManager.sol b/src/interfaces/IFeeManager.sol index 531cfc3..49bf99d 100644 --- a/src/interfaces/IFeeManager.sol +++ b/src/interfaces/IFeeManager.sol @@ -4,19 +4,45 @@ pragma solidity >=0.8.13 <0.9.0; import {IFeeAMM} from "./IFeeAMM.sol"; interface IFeeManager is IFeeAMM { + error CannotChangeWithinBlock(); + error InsufficientFeeTokenBalance(); + event UserTokenSet(address indexed user, address indexed token); event ValidatorTokenSet(address indexed validator, address indexed token); event FeesDistributed(address indexed validator, address indexed token, uint256 amount); + /// @notice Transfers a validator's accumulated fee balance to their address and zeroes the + /// ledger. No-ops when the balance is zero. + /// @param validator The validator to pay out. + /// @param token The fee token to distribute. function distributeFees(address validator, address token) external; + /// @notice Returns the accumulated fee balance for a validator in a given token. + /// @param validator The validator address. + /// @param token The fee token address. + /// @return The amount of fees accumulated and pending distribution. function collectedFees(address validator, address token) external view returns (uint256); + /// @notice Sets the caller's preferred fee token for paying transaction fees. + /// Must be a USD-denominated TIP-20 registered in TIP20Factory. + /// @param token The USD-denominated TIP-20 token address. function setUserToken(address token) external; + /// @notice Sets the caller's preferred fee token for receiving transaction fees. + /// Must be a USD-denominated TIP-20 registered in TIP20Factory. + /// Reverts with `CannotChangeWithinBlock` if the caller is the current block's beneficiary. + /// @param token The USD-denominated TIP-20 token address. function setValidatorToken(address token) external; - function userTokens(address) external view returns (address); - - function validatorTokens(address) external view returns (address); + /// @notice Returns the raw stored fee token preference for a user. + /// Returns the zero address if no preference has been set. + /// @param user The user address. + /// @return The token address stored for the user, or zero if unset. + function userTokens(address user) external view returns (address); + + /// @notice Returns the raw stored fee token preference for a validator. + /// Returns the zero address if no preference has been set. + /// @param validator The validator address. + /// @return The token address stored for the validator, or zero if unset. + function validatorTokens(address validator) external view returns (address); } diff --git a/src/interfaces/INonce.sol b/src/interfaces/INonce.sol index 45da5d3..b2537c0 100644 --- a/src/interfaces/INonce.sol +++ b/src/interfaces/INonce.sol @@ -23,6 +23,15 @@ interface INonce { /// @notice Thrown when a nonce value would overflow error NonceOverflow(); + /// @notice Thrown when an expiring nonce has already been used + error ExpiringNonceReplay(); + + /// @notice Thrown when the expiring nonce set is full and cannot accept more entries + error ExpiringNonceSetFull(); + + /// @notice Thrown when the expiry timestamp for an expiring nonce is invalid + error InvalidExpiringNonceExpiry(); + /// @notice Get the current nonce for a specific account and nonce key /// @param account The account address /// @param nonceKey The nonce key (must be > 0, protocol nonce key 0 not supported) diff --git a/src/interfaces/ISignatureVerifier.sol b/src/interfaces/ISignatureVerifier.sol index 56df01e..b8a3afb 100644 --- a/src/interfaces/ISignatureVerifier.sol +++ b/src/interfaces/ISignatureVerifier.sol @@ -5,7 +5,9 @@ pragma solidity >=0.8.13 <0.9.0; /// @notice Interface for the TIP-1020 Signature Verification Precompile /// @dev Deployed at 0x5165300000000000000000000000000000000000 interface ISignatureVerifier { + /// @notice Thrown when the signature bytes are not in the expected encoding format error InvalidFormat(); + /// @notice Thrown when the signature verification fails error InvalidSignature(); /// @notice Recovers the signer of a Tempo signature (secp256k1, P256, WebAuthn). diff --git a/src/interfaces/IStablecoinDEX.sol b/src/interfaces/IStablecoinDEX.sol index e1a72f7..b4fdd31 100644 --- a/src/interfaces/IStablecoinDEX.sol +++ b/src/interfaces/IStablecoinDEX.sol @@ -75,19 +75,19 @@ interface IStablecoinDEX { ); event PairCreated(bytes32 indexed key, address indexed base, address indexed quote); - function MAX_PRICE() external view returns (uint32); + function MAX_PRICE() external pure returns (uint32); - function MAX_TICK() external view returns (int16); + function MAX_TICK() external pure returns (int16); - function MIN_PRICE() external view returns (uint32); + function MIN_PRICE() external pure returns (uint32); - function MIN_TICK() external view returns (int16); + function MIN_TICK() external pure returns (int16); - function TICK_SPACING() external view returns (int16); + function TICK_SPACING() external pure returns (int16); - function PRICE_SCALE() external view returns (uint32); + function PRICE_SCALE() external pure returns (uint32); - function MIN_ORDER_AMOUNT() external view returns (uint128); + function MIN_ORDER_AMOUNT() external pure returns (uint128); function nextOrderId() external view returns (uint128); diff --git a/src/interfaces/ITIP20.sol b/src/interfaces/ITIP20.sol index 86adc07..34f21b1 100644 --- a/src/interfaces/ITIP20.sol +++ b/src/interfaces/ITIP20.sol @@ -12,18 +12,23 @@ interface ITIP20 { /// @notice Error when an account has insufficient balance for the requested operation. error InsufficientBalance(uint256 currentBalance, uint256 expectedBalance, address); + /// @notice Error when an invalid token amount is provided. error InvalidAmount(); /// @notice Error when an invalid currency identifier is provided. error InvalidCurrency(); + /// @notice Error when an invalid quote token is provided. error InvalidQuoteToken(); - error InvalidBaseToken(); + /// @notice Error when an invalid token address is provided. error InvalidToken(); + /// @notice Error when an invalid transfer policy identifier is provided. error InvalidTransferPolicyId(); /// @notice Error when attempting to transfer to an invalid recipient address. error InvalidRecipient(); + /// @notice Error when an invalid supply cap value is provided. error InvalidSupplyCap(); + /// @notice Error when there is no opted-in supply for the operation. error NoOptedInSupply(); /// @notice Error when a transfer is blocked by the current transfer policy. @@ -31,7 +36,14 @@ interface ITIP20 { /// @notice Error when attempting to burn from a protected address. error ProtectedAddress(); + /// @notice Error when minting would exceed the supply cap. error SupplyCapExceeded(); + /// @notice Error when the transaction payload is invalid. + error InvalidPayload(); + /// @notice Error when the caller lacks authorization for the requested action. + error Unauthorized(); + /// @notice Error when that precompile instance has not been initialized yet. + error Uninitialized(); /// @notice Emitted when an allowance is set between owner and spender. /// @param owner The address that owns the tokens. @@ -183,8 +195,6 @@ interface ITIP20 { function symbol() external view returns (string memory); - function systemTransferFrom(address from, address to, uint256 amount) external returns (bool); - /// @notice Returns the total token supply. /// @return The total amount of tokens in circulation. function totalSupply() external view returns (uint256); @@ -195,10 +205,6 @@ interface ITIP20 { /// @return success True if the transfer was successful. function transfer(address to, uint256 amount) external returns (bool); - function transferFeePostTx(address to, uint256 refund, uint256 actualUsed) external; - - function transferFeePreTx(address from, uint256 amount) external; - /// @notice Transfers tokens from one address to another using allowance. /// @param from The address to transfer tokens from. /// @param to The address to transfer tokens to. @@ -236,7 +242,7 @@ interface ITIP20 { /// @dev Returns the total pending claimable reward amount, including stored balance and newly accrued rewards. /// @param account The address to query pending rewards for. /// @return The total pending claimable reward amount. - function getPendingRewards(address account) external view returns (uint256); + function getPendingRewards(address account) external view returns (uint128); // EIP-2612 Permit (TIP-1004) diff --git a/src/interfaces/ITIP20RewardsRegistry.sol b/src/interfaces/ITIP20RewardsRegistry.sol deleted file mode 100644 index 9dd08d5..0000000 --- a/src/interfaces/ITIP20RewardsRegistry.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MIT OR Apache-2.0 -pragma solidity >=0.8.13 <0.9.0; - -/// @title Interface for TIP20RewardsRegistry -/// @notice Registry contract for all TIP20 reward streams -interface ITIP20RewardsRegistry { - error StreamsAlreadyFinalized(); - error Unauthorized(); - - /// @notice Add a token to the registry for a given stream end time. - function addStream(uint128 endTime) external; - - /// @notice Finalize streams for all tokens ending at the current timestamp. - function finalizeStreams() external; - - function lastUpdatedTimestamp() external view returns (uint128); - - /// @notice Remove a stream before it ends (for cancellation). - function removeStream(uint128 endTime) external; - - function streamIndex(bytes32) external view returns (uint256); - - function streamsEndingAt(uint128, uint256) external view returns (address); -} diff --git a/src/interfaces/ITIP20RolesAuth.sol b/src/interfaces/ITIP20RolesAuth.sol index 66d6466..aabe4c6 100644 --- a/src/interfaces/ITIP20RolesAuth.sol +++ b/src/interfaces/ITIP20RolesAuth.sol @@ -2,11 +2,16 @@ pragma solidity >=0.8.13 <0.9.0; interface ITIP20RolesAuth { + /// @notice Thrown when the caller lacks the required role for the requested action error Unauthorized(); event RoleMembershipUpdated(bytes32 indexed role, address indexed account, address indexed sender, bool hasRole); event RoleAdminUpdated(bytes32 indexed role, bytes32 indexed newAdminRole, address indexed sender); + function hasRole(address account, bytes32 role) external view returns (bool); + + function getRoleAdmin(bytes32 role) external view returns (bytes32); + function grantRole(bytes32 role, address account) external; function revokeRole(bytes32 role, address account) external; diff --git a/src/interfaces/IValidatorConfig.sol b/src/interfaces/IValidatorConfig.sol index 977ee9a..9d86017 100644 --- a/src/interfaces/IValidatorConfig.sol +++ b/src/interfaces/IValidatorConfig.sol @@ -47,6 +47,35 @@ interface IValidatorConfig { string outboundAddress; } + /// @notice Get the total number of validators + /// @return The number of validators + function validatorCount() external view returns (uint64); + + /// @notice Get validator info by address + /// @param validatorAddress The validator's address + /// @return publicKey The validator's communication public key + /// @return active Whether the validator is active + /// @return index The validator's index + /// @return addr The validator's address + /// @return inboundAddress The validator's inbound address + /// @return outboundAddress The validator's outbound address + function validators(address validatorAddress) + external + view + returns ( + bytes32 publicKey, + bool active, + uint64 index, + address addr, + string memory inboundAddress, + string memory outboundAddress + ); + + /// @notice Get validator address at a given array index + /// @param index The index in the validators array + /// @return The validator's address + function validatorsArray(uint256 index) external view returns (address); + /// @notice Get the complete set of validators /// @return validators Array of all validators with their information function getValidators() external view returns (Validator[] memory validators); diff --git a/src/interfaces/IValidatorConfigV2.sol b/src/interfaces/IValidatorConfigV2.sol index 18f03ec..35028b9 100644 --- a/src/interfaces/IValidatorConfigV2.sol +++ b/src/interfaces/IValidatorConfigV2.sol @@ -75,6 +75,9 @@ interface IValidatorConfigV2 { /// @notice Thrown when the Ed25519 signature verification fails error InvalidSignature(); + /// @notice Thrown when the signature bytes are not in the expected format + error InvalidSignatureFormat(); + /// @notice Thrown when V2 is not yet initialized (writes blocked before init) error NotInitialized();