SRC-8187 Token Puller — Reference Implementation
SRC-8187 Token Puller — Reference Implementation
Reference implementation for Token Puller, a standardized interface for permissioned, on-demand token pulls with custom sourcing logic, permit support, and allowance delegation.
Overview
A Puller contract acts as an intermediary that:
- Manages pull allowances granted by owners to spenders
- Executes custom sourcing logic to obtain tokens (e.g., withdrawing from a vault)
- Transfers the sourced tokens to a requested destination
- Supports SIP-712 signed permits and allowance delegation
Project Structure
contracts/
├── interfaces/IPuller.sol — Full SRC-8187 interface with natspec docs
├── base/BasePuller.sol — Abstract base: approvals, SIP-712 permits, allowance delegation
└── pullers/SRC4626Puller.sol — Sources tokens via SRC-4626 vault withdrawal
IPuller
The interface defining all events (PullApproval, TokensPulled, TransferPullAllowance) and functions (approvePull, pullFrom, pullAllowance, maxPullable, transferPullAllowance, permitPull, pullFromWithPermit, sip712Domain, nonces)
See IPuller.sol.
BasePuller
Abstract base contract implementing:
- Allowance storage and consumption with infinite-allowance skip
transferPullAllowancewith special infinite-allowance transfer and renunciation (toSpender == address(0))permitPullvia SIP-712 (ECDSA.recoverCalldatafor EOA signatures)- TODO: Support for SRC-6492 (universal signature validation) and SRC-1271 (smart contract wallets)
pullFromWithPermitwith front-run DoS protection (silent permit failure fallback)- Abstract
_sourceTokens(address token, address owner, address to, uint256 amount)andmaxPullable
Uses OpenZeppelin’s SIP712 for domain separators, ECDSA for signature recovery, and SafeSRC20 for token transfers.
See BasePuller.sol.
SRC4626Puller
Concrete puller paired with a single SRC-4626 vault. Its _sourceTokens calls vault.withdraw(amount, to, owner) — the vault’s own SRC-20 allowance mechanism consumes the owner’s share approval, burns shares, and sends the underlying asset directly to the destination.
See SRC4626Puller.sol.