← Digital Assets
EVM signing policies
Set signing rules for contract calls, typed authorizations, and account delegation.
Contract methods
Choose which contract methods your key may authorize. Check decoded arguments, chain ID, gas limits, and attached ETH.
Integration guideEdict exampletransfer-limits.edict
authority "transfer-limits" {
intent = "evm.transaction"
version = "1"
config {
chainId = 1
}
contract usdc: evm {
address = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
fn transfer(to: address, amount: uint256)
fn approve(spender: address, amount: uint256)
}
let USDC = 1000000
let router = "0xe592427a0aece92de3edee1f18e0157c05861564"
approver treasury {
type = "reference"
id = "treasury"
ref = "treasury@sha256:<digest>"
}
approver security {
type = "reference"
id = "security"
ref = "security@sha256:<digest>"
}
policy "token-spending" {
allow "transfer" when {
usdc.transfer != null
usdc.transfer.amount > 0
usdc.transfer.amount <= 10000 * USDC
transaction.value == 0
transaction.gasLimit <= 100000
}
allow "bounded-allowance" when {
usdc.approve != null
usdc.approve.spender == router
usdc.approve.amount > 0
usdc.approve.amount <= 1000 * USDC
transaction.value == 0
}
allow "revoke-allowance" when {
usdc.approve != null
usdc.approve.amount == 0
transaction.value == 0
}
require 2 of [treasury, security] if (
usdc.transfer != null and usdc.transfer.amount > 1000 * USDC
)
require security if (usdc.approve != null and usdc.approve.amount > 0)
}
}
Typed token authorizations
Set amount and expiry limits for ERC-3009 transfers and ERC-2612 permits. Restrict the token contract and decide when a request needs approval.
Integration guideEdict exampleshowcase-transfer-authorization.edict
authority "showcase-transfer-authorization" {
intent = "evm.3009"
version = "1"
config {
chainId = 1
}
let USDC = 1000000
approver treasury {
type = "reference"
id = "treasury"
ref = "treasury@sha256:<digest>"
}
approver security {
type = "reference"
id = "security"
ref = "security@sha256:<digest>"
}
policy "relayed-usdc-payment" {
let now = Time.now().toSeconds()
allow when {
operation == "transferWithAuthorization"
domain.name == "USD Coin"
domain.version == "2"
domain.verifyingContract == "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
transfer != null
transfer.value > 0
transfer.value <= 10000 * USDC
transfer.validAfter <= now
transfer.validBefore > now
transfer.validBefore <= now + 300
}
require 2 of [treasury, security] if (
transfer != null and transfer.value > 1000 * USDC
)
}
}
Structured call arguments
Declare structs and arrays in a contract interface. Write rules that compare decoded fields with each other or with values such as the current time.
Integration guideEdict exampleshowcase-swap.edict
authority "showcase-swap" {
intent = "evm.transaction"
version = "1"
config {
chainId = 1
}
contract router: evm {
address = "0xe592427a0aece92de3edee1f18e0157c05861564"
struct ExactOutput {
tokenIn: address
tokenOut: address
fee: uint24
recipient: address
deadline: uint256
amountOut: uint256
amountInMaximum: uint256
sqrtPriceLimitX96: uint160
}
fn exactOutputSingle(params: ExactOutput)
}
let WETH = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
let USDC = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
approver treasury {
type = "reference"
id = "treasury"
ref = "treasury@sha256:<digest>"
}
approver security {
type = "reference"
id = "security"
ref = "security@sha256:<digest>"
}
policy "reviewed-swap" {
let swap = router.exactOutputSingle.params
allow when {
swap.tokenIn == WETH
swap.tokenOut == USDC
swap.fee == 3000
swap.amountOut > 0
swap.amountInMaximum > 0
swap.amountInMaximum <= 1000000000000000000
swap.deadline > Time.now().toSeconds()
swap.deadline <= Time.now().toSeconds() + 300
transaction.value == 0
transaction.gasLimit <= 250000
}
require 2 of [treasury, security]
}
}
EIP-7702 delegation
Choose which contracts may act for an account. Restrict the chain and nonce, and require approval before signing a delegation.
Integration guideEdict exampledelegation-control.edict
authority "delegation-control" {
intent = "evm.7702"
version = "1"
config {
chainId = 1
}
approver security {
type = "reference"
id = "security"
ref = "security@sha256:<digest>"
}
policy "delegation-control" {
allow when {
chainId == 1
address == "0x1111111111111111111111111111111111111111"
nonce == 7
}
require security
}
}