Abstract
This EIP introduces the Instruction Specific Address (ISA) mechanism, which allows for approval-less interactions with decentralized applications (DApps) through the use of dynamically generated single-use addresses. By enabling transactions without wallet connections or approvals, ISA enhances user security, simplifies interactions, and aligns Web3 interfaces with familiar Web 2.0 paradigms.
The ISA mechanism supports compatibility with centralized exchange (CEX) wallets and existing wallet infrastructures while ensuring a unified, blockchain-agnostic experience. It limits user risk by isolating wallets from DApps and ensures that the maximum capital at risk is only the amount transferred. This standard aims to bridge the usability gap between centralized and decentralized applications, fostering wider adoption of Web3 technologies.
Motivation
The current Web3 interaction paradigm often involves complex wallet connections, approvals, and transaction signing, which introduces several challenges:
- Usability Friction: The need to connect wallets, approve transactions, and handle prompts deters mainstream users accustomed to seamless Web 2.0 experiences.
- Security Risks: Wallet-DApp integration exposes users to phishing, signing hacks, and malicious contract interactions.
- Limited Access: The reliance on browser wallet plugins or extensions creates barriers for users on platforms without wallet integrations.
The Instruction Specific Address (ISA) mechanism addresses these challenges by:
- Approval-Less Interactions: Allowing users to interact with DApps directly, eliminating the need for wallet approvals.
- Wallet Isolation: Detaching wallets from DApps to prevent phishing and tunneling attacks.
- Centralized Exchange Integration: Enabling transactions using wallets from centralized exchanges (CEXs).
- Broad Accessibility: Supporting interactions on platforms where no wallet is installed, enhancing multi-platform usability.
- Unified Experience: Offering a seamless, blockchain-agnostic approach that translates to Web 2.0-like product philosophies.
By adopting ISA, the Web3 ecosystem can enhance security, improve user experience, and pave the way for broader adoption of decentralized technologies.
Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.
Glossary of Terms
- Instruction Specific Address (ISA): A dynamically generated, single-use contract address designed to facilitate approval-less contract interactions.
- CallOps: A standardized structure defining the parameters for an ISA interaction, enabling seamless interoperability.
- Relayer: A participant responsible for executing ISA operations and collecting fees.
- RefundRecipient: An address specified by the user to receive refunds in case of failed interactions.
- TargetAddress: The destination contract address for the ISA operation.
- ApprovalAddress: The address responsible for approving token transfers, if necessary.
CallOps Structure
ISA interactions MUST adhere to the standardized CallOps structure for compatibility and interoperability across platforms:
/// @title CallOps Structure
/// @notice Defines the parameters for executing an ISA operation
struct CallOps {
/// @dev The target contract address for the operation
address targetAddress;
/// @dev Address responsible for approving token transfers, if applicable
address approvalAddress;
/// @dev Encoded data for the transaction to execute
bytes executionData;
/// @dev The token being transferred (use address(0) for native assets)
address sourceToken;
/// @dev Address to receive refunds in case of failed interaction
address refundRecipient;
/// @dev Address of the relayer responsible for execution
address relayerAddress;
/// @dev Fee paid to the relayer for execution
uint256 relayerFee;
}The CallOps structure enables consistent and interoperable ISA interactions, simplifying integration for developers.
Address Generation
ISA relies on deterministic address generation using the CREATE2 opcode. The ISAFactory contract MUST implement a generateAddress function to compute the ISA address:
/// @title ISAFactory Contract
/// @notice Generates deterministic ISA addresses using CREATE2
contract ISAFactory {
function generateAddress(
bytes32 salt,
bytes memory initializationCode
) public view returns (address) {
return address(uint160(uint256(
keccak256(
abi.encodePacked(
hex"ff",
address(this),
salt,
keccak256(initializationCode)
)
)
)));
}
}This deterministic approach ensures compatibility across applications and ecosystems.
Relevant Events
ISA MUST emit the following events to signal state transitions and enhance observability:
/// @notice Emitted upon successful execution of the ISA
/// @param targetAddress The target contract address
/// @param amountTransferred The amount of tokens or assets transferred
event ExecutionSucceeded(address indexed relayerAddress, address indexed targetAddress, uint256 amountTransferred);
/// @notice Emitted when an ISA execution fails
/// @param targetAddress The target contract address
/// @param reason The reason for failure
event ExecutionFailed(address indexed relayerAddress, address indexed targetAddress, string reason);
/// @notice Emitted when a refund is issued to the specified recipient
/// @param refundRecipient The address receiving the refund
/// @param amount The amount refunded
event RefundIssued(address indexed refundRecipient, uint256 amount);These events ensure transparency for users and developers while providing critical operational feedback.
Lifecycle of an ISA Interaction
-
Address Creation:
- A user requests an ISA for a specific interaction by providing necessary parameters.
- The ISAFactory generates a deterministic address using
CREATE2.
-
Asset Transfer:
- The user sends assets (e.g., ERC-20 tokens or native currency) to the generated ISA address.
-
Execution:
- The ISA executes the transaction using the
CallOpsparameters. - If successful, the target contract receives the assets and executes the specified logic.
- The ISA executes the transaction using the
-
Refund Mechanism:
- If the transaction fails, the ISA refunds remaining assets to the specified
refundRecipient.
- If the transaction fails, the ISA refunds remaining assets to the specified
-
Self-Destruction:
- After execution or refund, the ISA self-destructs to free resources and ensure it cannot be reused.
Compliance and Integration
- Wallet Support: ISA MUST support all existing wallets and enable interactions using centralized exchange (CEX) wallets.
- Blockchain Agnosticism: ISA MUST NOT rely on protocol-specific features, ensuring compatibility across EVM and non-EVM chains.
- Relayer Standards: Relayers MUST adhere to the
CallOpsstructure and follow standardized execution practices.
Rationale
Approval-less Contract Interactions
Current DApp interactions require users to connect wallets, approve transactions, and grant permissions, which introduces complexity and security vulnerabilities. ISA eliminates these steps by enabling direct, approval-less interactions, mitigating the following risks:
- Phishing Attacks: ISAs isolate wallet credentials from DApps, preventing unauthorized access and signature-based exploits.
- Wallet Tunneling: Without wallet connections, DApps cannot tunnel into user wallets to execute unintended actions.
- Approval-based Risks: By removing the need for token approvals, ISA eliminates scenarios where excessive allowances are exploited.
Security Enhancements
ISAs are designed with the principle of minimizing risk exposure:
- Limited Capital at Risk: The maximum funds at risk in any ISA interaction are the amount transferred to the ISA.
- Refund Mechanisms: ISA ensures users receive refunds for any unspent or unused assets in case of transaction failure.
Familiar and Seamless UX
ISA provides a Web2-like experience for Web3 interactions:
- Scan-and-Pay Simplicity: Users can interact with DApps by scanning a QR code and transferring funds without wallet connections.
- No Wallet Plugins Required: ISA enables interactions in browsers or platforms where wallets are not installed, broadening accessibility.
- Centralized Exchange (CEX) Compatibility: Users can execute DApp transactions directly using CEX wallets, making the system accessible to a broader user base.
Interoperability and Extensibility
- Blockchain Agnosticism: ISA is designed to be compatible across multiple blockchain ecosystems, ensuring no dependency on a specific protocol or network.
- Relayer Flexibility: The standardized
CallOpsstructure ensures that ISAs are compatible with multiple relayer networks, fostering competition and innovation. - Protocol-Neutral Implementation: ISA focuses on universal interaction standards and does not depend on Router Protocol or any specific bridging system.
Enhanced Developer Experience
ISA simplifies DApp integration:
- Unified Interaction Model: Developers can build applications that interact seamlessly with ISAs across chains and wallets.
- Simplified State Management: By isolating state changes to ISA contracts, DApps can reduce complexity in managing user interactions.
Resilience to Edge Cases
ISAs address potential failure scenarios:
- Data Availability Layers: To mitigate the risk of lost data used for address generation, ISAs can leverage data availability (DA) layers to persist and retrieve the required data.
- Refund Fallbacks: In case of incorrect or unreachable
refundRecipientaddresses, ISA reverts the refund to the sender, ensuring user funds are not lost.
Alignment with Payment and Product Philosophies
ISA embodies a payment-first approach:
- First CTA is Action, Not Wallet Connection: Users are encouraged to engage with the DApp's functionality first, removing the "connect wallet" barrier.
- Unified Chain Experience: By decoupling wallet requirements, ISA creates a consistent and seamless experience across platforms and ecosystems.
Compatibility with Existing Standards
ISA is designed to align with and complement existing Ethereum standards:
- EIP-7683 (Cross-Chain Intents): ISA supports interaction paradigms that abstract user intent across chains.
- Broad Compatibility: ISA ensures that its features are generic and protocol-agnostic, allowing integration with future standards.
Let me know if this meets your expectations or if further elaboration is needed! If all is good, we can proceed to the next section.
Backwards Compatibility
The Instruction Specific Address (ISA) mechanism is designed to be compatible with existing Ethereum infrastructure while introducing novel interaction paradigms. Below are the considerations for backward compatibility:
Wallet Compatibility
- Existing Wallets: ISA supports all existing wallets that comply with ERC-20 and native token standards. Users can utilize their current wallets to interact with ISAs without requiring additional configuration or updates.
- Centralized Exchange (CEX) Wallets: ISA enables seamless interaction using CEX wallets, expanding the scope of wallet compatibility beyond traditional self-custodial solutions.
Contract Interactions
- Target Contracts: ISAs can interact with any existing smart contracts. However, target contracts SHOULD NOT rely on
msg.senderfor critical state ownership, as the ISA contract will be themsg.senderduring execution. - Standard Token Contracts: ISA supports all ERC-20 tokens and native assets. Token approval mechanisms are replaced with direct transfers managed within the ISA lifecycle.
Deterministic Address Generation
The CREATE2 opcode ensures deterministic address generation for ISAs, providing compatibility with any system that supports this opcode. This approach maintains consistency across deployments and eliminates conflicts with existing address schemes.
Event Logging and Observability
ISA introduces new events to enhance transparency and enable developers to track interactions efficiently. These events are additive and do not interfere with existing event structures used by other standards.
Cross-Chain Compatibility
While primarily focused on EVM-based chains, ISA’s protocol-neutral implementation ensures that it can be extended to non-EVM ecosystems. Its reliance on generic terms and abstraction layers allows for interoperability across diverse blockchain environments.
Non-Disruptive Integration
ISA is an opt-in mechanism that does not impose changes on existing systems. DApps and developers can integrate ISA without modifying their existing contract logic, ensuring a smooth transition and adoption process.
Reference Implementation
This section provides a reference implementation of the Instruction Specific Address (ISA) mechanism. The implementation includes key contracts to demonstrate the address generation, transaction processing, and event emission capabilities of ISAs.
ISAFactory Contract
The ISAFactory contract generates deterministic ISA addresses using the CREATE2 opcode and emits events for transparency.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title ISAFactory
/// @notice Generates deterministic ISA addresses using CREATE2
contract ISAFactory {
/// @notice Generates a deterministic ISA address
/// @param salt A unique value to differentiate addresses
/// @param initializationCode The bytecode of the ISA
/// @return address The generated ISA address
function generateAddress(
bytes32 salt,
bytes memory initializationCode
) public view returns (address) {
address generatedAddress = address(uint160(uint256(
keccak256(
abi.encodePacked(
hex"ff",
address(this),
salt,
keccak256(initializationCode)
)
)
)));
return generatedAddress;
}
}DepositReceiver Contract
The DepositReceiver contract handles transactions for ISAs, processes user-defined logic, and emits events for transaction completion or failure.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title DepositReceiver
/// @notice A temporary contract for processing ISA transactions
contract DepositReceiver {
constructor(bytes memory executionData, address refundRecipient) payable {
bool success;
(success, ) = msg.sender.delegatecall(executionData);
if (!success) {
// Emit event for failed transaction
// Revert with the original error data
assembly {
let ptr := mload(0x40)
let size := returndatasize()
returndatacopy(ptr, 0, size)
revert(ptr, size)
}
}
if (refundRecipient == address(0)) {
refundRecipient = msg.sender;
}
selfdestruct(payable(refundRecipient));
}
/// @dev This function allows the contract to accept Ether
receive() external payable {}
}Execution Contract
The ExecutionContract processes and forwards ISA transactions, ensuring transparency by emitting events for all state changes.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import 'lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol';
/// @title ExecutionContract
/// @notice Handles transaction processing and asset forwarding for ISAs
contract ExecutionContract {
struct CallOps {
address targetAddress;
address approvalAddress;
bytes executionData;
address sourceToken;
address refundRecipient;
address relayerAddress;
uint256 relayerFee;
}
/// @notice Emitted upon successful execution of the ISA
/// @param relayerAddress The relayer's address handling the transaction
/// @param targetAddress The target contract address
/// @param amountTransferred The amount of tokens or assets transferred
event ExecutionSucceeded(address indexed relayerAddress, address indexed targetAddress, uint256 amountTransferred);
/// @notice Emitted when an ISA execution fails
/// @param relayerAddress The relayer's address handling the transaction
/// @param targetAddress The target contract address
/// @param reason The reason for failure
event ExecutionFailed(address indexed relayerAddress, address indexed targetAddress, string reason);
/// @notice Emitted when a refund is issued to the specified recipient
/// @param refundRecipient The address receiving the refund
/// @param amount The amount refunded
event RefundIssued(address indexed refundRecipient, uint256 amount);
/// @notice Processes ISA transactions
/// @param callOps Encoded call operation parameters
function processCallOps(CallOps calldata callOps) external payable {
uint256 amount = msg.value;
// Check if the token is ERC20 or native asset
if (callOps.sourceToken != address(0)) {
amount = IERC20(callOps.sourceToken).balanceOf(address(this));
IERC20(callOps.sourceToken).approve(callOps.approvalAddress, amount);
}
// Try executing the call
(bool success, bytes memory returnData) = callOps.targetAddress.call{ value: amount }(callOps.executionData);
if (success) {
// Emit event for successful execution
emit ExecutionSucceeded(callOps.relayerAddress, callOps.targetAddress, amount);
} else {
// Emit event for execution failure
string memory reason = _getRevertReason(returnData);
emit ExecutionFailed(callOps.relayerAddress, callOps.targetAddress, reason);
// Handle refunds on failure
if (callOps.refundRecipient != address(0)) {
if (callOps.sourceToken != address(0)) {
IERC20(callOps.sourceToken).transfer(callOps.refundRecipient, amount);
} else {
payable(callOps.refundRecipient).transfer(amount);
}
emit RefundIssued(callOps.refundRecipient, amount);
}
}
}
/// @dev Decodes the revert reason from the returned data
/// @param returnData The data returned from the failed call
/// @return reason The decoded revert reason string
function _getRevertReason(bytes memory returnData) internal pure returns (string memory reason) {
if (returnData.length < 68) return "Transaction failed without a reason";
assembly {
returnData := add(returnData, 0x04)
reason := mload(returnData)
}
}
/// @dev This function allows the contract to accept Ether
receive() external payable {}
}Security Considerations
Evaluating ISA Contract Security
This ERC is agnostic of how the Instruction Specific Address (ISA) mechanism validates and processes interactions, including refunds and transaction execution. The security of the ISA contract's lifecycle, from creation to execution and self-destruction, is delegated to developers implementing the standard and the applications utilizing it.
This design decision allows flexibility in implementation, accommodating diverse use cases while ensuring ISA remains adaptable across ecosystems. However, it also places the responsibility of contract auditing, relayer integrity, and event observability on developers and integrators.
Leveraging Deterministic Address Generation
- The use of
CREATE2ensures deterministic address generation, allowing for predictable and verifiable ISA deployment. - Developers are responsible for ensuring that initialization parameters (e.g., salts and bytecode) are unique and immutable to avoid address collisions.
Safeguards Against Misuse
- The maximum capital exposed is limited to the assets explicitly transferred to the ISA, significantly reducing user risk.
- Refund logic ensures unspent funds are returned to the specified
refundRecipient.
Dependency on Relayers
- Developers and relayers must adhere to the
CallOpsstructure to maintain transaction integrity and prevent misuse of execution parameters. - Transparency is ensured through event emission, enabling continuous monitoring of relayer activities and transaction states.
Compatibility with Target Contracts
- ISAs rely on target contracts being agnostic to
msg.senderfor critical state changes. Developers of target contracts must ensure compatibility with this interaction model.
Copyright
Copyright and related rights waived via CC0.
