From 14dec6f6f337c268a8645237066a944b7f77c73a Mon Sep 17 00:00:00 2001 From: 0xrusowsky <0xrusowsky@proton.me> Date: Wed, 22 Apr 2026 17:54:31 +0200 Subject: [PATCH 1/6] feat: new abstract `StdBase` around `StdPrecompiles` lib --- src/StdBase.sol | 62 ++++++++++++++++++++++++++++++ src/StdPrecompiles.sol | 1 - src/interfaces/ITIP20.sol | 14 ++++--- src/interfaces/ITIP20RolesAuth.sol | 10 ++--- 4 files changed, 75 insertions(+), 12 deletions(-) create mode 100644 src/StdBase.sol diff --git a/src/StdBase.sol b/src/StdBase.sol new file mode 100644 index 0000000..2b3f62c --- /dev/null +++ b/src/StdBase.sol @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity >=0.8.13 <0.9.0; + +import {StdPrecompiles} from "./StdPrecompiles.sol"; +import {StdTokens} from "./StdTokens.sol"; +import {IAccountKeychain} from "./interfaces/IAccountKeychain.sol"; +import {IAddressRegistry} from "./interfaces/IAddressRegistry.sol"; +import {IFeeManager} from "./interfaces/IFeeManager.sol"; +import {INonce} from "./interfaces/INonce.sol"; +import {ISignatureVerifier} from "./interfaces/ISignatureVerifier.sol"; +import {IStablecoinDEX} from "./interfaces/IStablecoinDEX.sol"; +import {ITIP20} from "./interfaces/ITIP20.sol"; +import {ITIP20Factory} from "./interfaces/ITIP20Factory.sol"; +import {ITIP403Registry} from "./interfaces/ITIP403Registry.sol"; +import {IValidatorConfig} from "./interfaces/IValidatorConfig.sol"; +import {IValidatorConfigV2} from "./interfaces/IValidatorConfigV2.sol"; + +abstract contract StdBase { + // Nonce precompile + INonce public constant nonce = StdPrecompiles.NONCE_PRECOMPILE; + address public constant NONCE = StdPrecompiles.NONCE_ADDRESS; + + // Account keychain precompile + IAccountKeychain public constant keychain = StdPrecompiles.ACCOUNT_KEYCHAIN; + address public constant KEYCHAIN = StdPrecompiles.ACCOUNT_KEYCHAIN_ADDRESS; + + // Stablecoin DEX precompile + IStablecoinDEX public constant stableDEX = StdPrecompiles.STABLECOIN_DEX; + address public constant STABLE_DEX = StdPrecompiles.STABLECOIN_DEX_ADDRESS; + + // Fee manager precompile + IFeeManager public constant feeAMM = StdPrecompiles.TIP_FEE_MANAGER; + address public constant FEE_AMM = StdPrecompiles.TIP_FEE_MANAGER_ADDRESS; + + // TIP-403 registry precompile + ITIP403Registry public constant registry = StdPrecompiles.TIP403_REGISTRY; + address public constant REGISTRY = StdPrecompiles.TIP403_REGISTRY_ADDRESS; + + // TIP-20 address registry precompile + IAddressRegistry public constant tip20Registry = StdPrecompiles.ADDRESS_REGISTRY; + address public constant TIP20_REGISTRY = StdPrecompiles.ADDRESS_REGISTRY_ADDRESS; + + // Validator config precompile + IValidatorConfig public constant validatorConfig = StdPrecompiles.VALIDATOR_CONFIG; + address public constant VALIDATOR_CONFIG = StdPrecompiles.VALIDATOR_CONFIG_ADDRESS; + + // Validator config v2 precompile + IValidatorConfigV2 public constant validatorConfigV2 = StdPrecompiles.VALIDATOR_CONFIG_V2; + address public constant VALIDATOR_CONFIG_V2 = StdPrecompiles.VALIDATOR_CONFIG_V2_ADDRESS; + + // TIP-20 factory precompile + ITIP20Factory public constant factory = StdPrecompiles.TIP20_FACTORY; + address public constant FACTORY = StdPrecompiles.TIP20_FACTORY_ADDRESS; + + // Signature verifier precompile + ISignatureVerifier public constant signatureVerifier = StdPrecompiles.SIGNATURE_VERIFIER; + address public constant SIGNATURE_VERIFIER = StdPrecompiles.SIGNATURE_VERIFIER_ADDRESS; + + // pathUSD is just a TIP20 at a special address (0x20C0...) with token_id=0 + ITIP20 public constant pathUSD = StdTokens.PATH_USD; + address public constant PATH_USD = StdTokens.PATH_USD_ADDRESS; +} diff --git a/src/StdPrecompiles.sol b/src/StdPrecompiles.sol index 344f88f..e31f783 100644 --- a/src/StdPrecompiles.sol +++ b/src/StdPrecompiles.sol @@ -19,7 +19,6 @@ library StdPrecompiles { address internal constant TIP_FEE_MANAGER_ADDRESS = 0xfeEC000000000000000000000000000000000000; address internal constant TIP403_REGISTRY_ADDRESS = 0x403c000000000000000000000000000000000000; address internal constant TIP20_FACTORY_ADDRESS = 0x20Fc000000000000000000000000000000000000; - address internal constant TIP20_REWARDS_REGISTRY_ADDRESS = 0x2100000000000000000000000000000000000000; address internal constant STABLECOIN_DEX_ADDRESS = 0xDEc0000000000000000000000000000000000000; address internal constant NONCE_ADDRESS = 0x4e4F4E4345000000000000000000000000000000; address internal constant VALIDATOR_CONFIG_ADDRESS = 0xCccCcCCC00000000000000000000000000000000; diff --git a/src/interfaces/ITIP20.sol b/src/interfaces/ITIP20.sol index 34f21b1..e74102a 100644 --- a/src/interfaces/ITIP20.sol +++ b/src/interfaces/ITIP20.sol @@ -1,9 +1,11 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.8.13 <0.9.0; -/// @title The interface for TIP-20 compliant tokens -/// @notice A token standard that extends ERC-20 with additional features including transfer policies, memo support, and pause functionality -interface ITIP20 { +import {ITIP20RolesAuth, ITIP20RolesAuthErr} from "./ITIP20RolesAuth.sol"; + +/// @title The interface for interacting with core TIP-20 token features. +/// @dev If you also need role authorization capabilities, use `ITIP20Token`. +interface ITIP20 is ITIP20RolesAuthErr { /// @notice Error when attempting an operation while the contract is paused. error ContractPaused(); @@ -40,8 +42,6 @@ interface ITIP20 { 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(); @@ -262,3 +262,7 @@ interface ITIP20 { /// @notice Returns the EIP-712 domain separator for this token function DOMAIN_SEPARATOR() external view returns (bytes32); } + +/// @title The interface for TIP-20 compliant tokens +/// @notice A token standard that extends ERC-20 with additional features including transfer policies, memo support, and pause functionality +interface ITIP20Token is ITIP20, ITIP20RolesAuth {} diff --git a/src/interfaces/ITIP20RolesAuth.sol b/src/interfaces/ITIP20RolesAuth.sol index aabe4c6..a13af45 100644 --- a/src/interfaces/ITIP20RolesAuth.sol +++ b/src/interfaces/ITIP20RolesAuth.sol @@ -1,22 +1,20 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.8.13 <0.9.0; -interface ITIP20RolesAuth { +interface ITIP20RolesAuthErr { /// @notice Thrown when the caller lacks the required role for the requested action error Unauthorized(); +} +/// @title The interface for interacting with TIP-20 token authorization-related features. +interface ITIP20RolesAuth { 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; - function renounceRole(bytes32 role) external; - function setRoleAdmin(bytes32 role, bytes32 adminRole) external; } From 5ec8ac653ced663efb7634a29ee05e65a33ef3f1 Mon Sep 17 00:00:00 2001 From: 0xrusowsky <0xrusowsky@proton.me> Date: Wed, 22 Apr 2026 18:02:50 +0200 Subject: [PATCH 2/6] chore: rename to TIP20_FACTORY --- src/StdBase.sol | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/StdBase.sol b/src/StdBase.sol index 2b3f62c..46b44b0 100644 --- a/src/StdBase.sol +++ b/src/StdBase.sol @@ -32,14 +32,6 @@ abstract contract StdBase { IFeeManager public constant feeAMM = StdPrecompiles.TIP_FEE_MANAGER; address public constant FEE_AMM = StdPrecompiles.TIP_FEE_MANAGER_ADDRESS; - // TIP-403 registry precompile - ITIP403Registry public constant registry = StdPrecompiles.TIP403_REGISTRY; - address public constant REGISTRY = StdPrecompiles.TIP403_REGISTRY_ADDRESS; - - // TIP-20 address registry precompile - IAddressRegistry public constant tip20Registry = StdPrecompiles.ADDRESS_REGISTRY; - address public constant TIP20_REGISTRY = StdPrecompiles.ADDRESS_REGISTRY_ADDRESS; - // Validator config precompile IValidatorConfig public constant validatorConfig = StdPrecompiles.VALIDATOR_CONFIG; address public constant VALIDATOR_CONFIG = StdPrecompiles.VALIDATOR_CONFIG_ADDRESS; @@ -48,14 +40,22 @@ abstract contract StdBase { IValidatorConfigV2 public constant validatorConfigV2 = StdPrecompiles.VALIDATOR_CONFIG_V2; address public constant VALIDATOR_CONFIG_V2 = StdPrecompiles.VALIDATOR_CONFIG_V2_ADDRESS; - // TIP-20 factory precompile - ITIP20Factory public constant factory = StdPrecompiles.TIP20_FACTORY; - address public constant FACTORY = StdPrecompiles.TIP20_FACTORY_ADDRESS; - // Signature verifier precompile ISignatureVerifier public constant signatureVerifier = StdPrecompiles.SIGNATURE_VERIFIER; address public constant SIGNATURE_VERIFIER = StdPrecompiles.SIGNATURE_VERIFIER_ADDRESS; + // TIP-403 registry precompile + ITIP403Registry public constant registry = StdPrecompiles.TIP403_REGISTRY; + address public constant REGISTRY = StdPrecompiles.TIP403_REGISTRY_ADDRESS; + + // TIP-20 address registry precompile + IAddressRegistry public constant tip20Registry = StdPrecompiles.ADDRESS_REGISTRY; + address public constant TIP20_REGISTRY = StdPrecompiles.ADDRESS_REGISTRY_ADDRESS; + + // TIP-20 factory precompile + ITIP20Factory public constant tip20Factory = StdPrecompiles.TIP20_FACTORY; + address public constant TIP20_FACTORY = StdPrecompiles.TIP20_FACTORY_ADDRESS; + // pathUSD is just a TIP20 at a special address (0x20C0...) with token_id=0 ITIP20 public constant pathUSD = StdTokens.PATH_USD; address public constant PATH_USD = StdTokens.PATH_USD_ADDRESS; From 3645595639a96ac8e0bd52b74f7f9832b5f94fef Mon Sep 17 00:00:00 2001 From: 0xrusowsky <0xrusowsky@proton.me> Date: Wed, 22 Apr 2026 18:07:56 +0200 Subject: [PATCH 3/6] style: rename to `Tempo` --- src/StdBase.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/StdBase.sol b/src/StdBase.sol index 46b44b0..4c49d7e 100644 --- a/src/StdBase.sol +++ b/src/StdBase.sol @@ -15,7 +15,7 @@ import {ITIP403Registry} from "./interfaces/ITIP403Registry.sol"; import {IValidatorConfig} from "./interfaces/IValidatorConfig.sol"; import {IValidatorConfigV2} from "./interfaces/IValidatorConfigV2.sol"; -abstract contract StdBase { +abstract contract Tempo { // Nonce precompile INonce public constant nonce = StdPrecompiles.NONCE_PRECOMPILE; address public constant NONCE = StdPrecompiles.NONCE_ADDRESS; From 2fbc9cba5224b0bcbab6171cce208d9480d56ef3 Mon Sep 17 00:00:00 2001 From: 0xrusowsky <0xrusowsky@proton.me> Date: Wed, 22 Apr 2026 18:14:19 +0200 Subject: [PATCH 4/6] style: rename file too --- src/{StdBase.sol => Tempo.sol} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{StdBase.sol => Tempo.sol} (100%) diff --git a/src/StdBase.sol b/src/Tempo.sol similarity index 100% rename from src/StdBase.sol rename to src/Tempo.sol From 57cb56b7e4f47877d58895883c56227683ef7018 Mon Sep 17 00:00:00 2001 From: 0xrusowsky <0xrusowsky@proton.me> Date: Wed, 22 Apr 2026 18:20:12 +0200 Subject: [PATCH 5/6] style: rename for clarity --- src/Tempo.sol | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Tempo.sol b/src/Tempo.sol index 4c49d7e..24360dc 100644 --- a/src/Tempo.sol +++ b/src/Tempo.sol @@ -45,12 +45,12 @@ abstract contract Tempo { address public constant SIGNATURE_VERIFIER = StdPrecompiles.SIGNATURE_VERIFIER_ADDRESS; // TIP-403 registry precompile - ITIP403Registry public constant registry = StdPrecompiles.TIP403_REGISTRY; - address public constant REGISTRY = StdPrecompiles.TIP403_REGISTRY_ADDRESS; + ITIP403Registry public constant tip403Registry = StdPrecompiles.TIP403_REGISTRY; + address public constant TIP403_REGISTRY = StdPrecompiles.TIP403_REGISTRY_ADDRESS; - // TIP-20 address registry precompile - IAddressRegistry public constant tip20Registry = StdPrecompiles.ADDRESS_REGISTRY; - address public constant TIP20_REGISTRY = StdPrecompiles.ADDRESS_REGISTRY_ADDRESS; + // Address registry precompile + IAddressRegistry public constant addrRegistry = StdPrecompiles.ADDRESS_REGISTRY; + address public constant ADDRESS_REGISTRY = StdPrecompiles.ADDRESS_REGISTRY_ADDRESS; // TIP-20 factory precompile ITIP20Factory public constant tip20Factory = StdPrecompiles.TIP20_FACTORY; From 40c9996cf38bbc15b19b5260c997b46457dcf188 Mon Sep 17 00:00:00 2001 From: 0xrusowsky <0xrusowsky@proton.me> Date: Wed, 22 Apr 2026 18:48:25 +0200 Subject: [PATCH 6/6] fix: missing error --- src/interfaces/ITIP20RolesAuth.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces/ITIP20RolesAuth.sol b/src/interfaces/ITIP20RolesAuth.sol index a13af45..337f92e 100644 --- a/src/interfaces/ITIP20RolesAuth.sol +++ b/src/interfaces/ITIP20RolesAuth.sol @@ -7,7 +7,7 @@ interface ITIP20RolesAuthErr { } /// @title The interface for interacting with TIP-20 token authorization-related features. -interface ITIP20RolesAuth { +interface ITIP20RolesAuth is ITIP20RolesAuthErr { event RoleMembershipUpdated(bytes32 indexed role, address indexed account, address indexed sender, bool hasRole); event RoleAdminUpdated(bytes32 indexed role, bytes32 indexed newAdminRole, address indexed sender);