Skip to main content

Mock Protocol Reference

MockDeFiProtocol is the reference implementation deployed in this sandbox. It shows the minimal contract shape needed to integrate DS Token with VaultRegistrar: one vault per investor, created on first deposit, registered with an EIP-712 signature in the same transaction.

Use it as a starting point when designing your own protocol contract.

What it does

  • Deploys a per-investor vault on first deposit() call.
  • Calls VaultRegistrar.registerVault() with the investor's EIP-712 signature in the same transaction.
  • Pulls DS Tokens from the investor's wallet into the vault via transferFrom.
  • Emits VaultCreated and Deposit events.
  • Provides withdraw(amount) to return tokens to the investor.
  • Provides clearVault(investor) and clearMyVault() as admin escape hatches.

Interface

// Constructor
constructor(address _vaultRegistrar, address _dsToken)

// Core flow
function deposit(uint256 amount, uint256 deadline, bytes calldata signature) external

// Off-ramp
function withdraw(uint256 amount) external

// Admin escape hatches
function clearVault(address investor) external
function clearMyVault() external

// View
function investorVaults(address investor) external view returns (address vault)
function dsToken() external view returns (address)
function vaultRegistrar() external view returns (address)

Events

event VaultCreated(address indexed investor, address indexed vault)
event Deposit(address indexed investor, address indexed vault, uint256 amount)
event Withdraw(address indexed investor, address indexed vault, uint256 amount)

How deposit() works

investor wallet

│ 1. signTypedData(RegisterVault { investor, operator: MockDeFiProtocol, ... })


MockDeFiProtocol.deposit(amount, deadline, signature)

├─ 2. Deploy MockVault for investor (if not already deployed)
│ emit VaultCreated(investor, vault)

├─ 3. VaultRegistrar.registerVault(vault, investor, deadline, signature)
│ ↳ verifies EIP-712 signature
│ ↳ links vault → investor in DS registry
│ ↳ emit VaultRegistered(...)

└─ 4. DSToken.transferFrom(investor, vault, amount)
↳ succeeds because vault is now registered
↳ emit Deposit(investor, vault, amount)

Critical: the operator in the EIP-712 signature

The operator field in the RegisterVault typed-data message must equal msg.sender of the registerVault() call. Since MockDeFiProtocol is the contract calling registerVault(), the investor must sign with:

operator = MockDeFiProtocol contract address

Not the deployer EOA. Not the investor's wallet. Not any backend relay address.

This is the most common cause of InvalidInvestorSignature(). The sandbox UI (Mock Protocol Example) handles this correctly automatically.

The deposit prerequisite checklist

Before deposit() will succeed:

RequirementHow to satisfy
MockDeFiProtocol has OPERATOR_ROLE on VaultRegistrarPermissionless on testnet — call addOperator(mockProtocolAddress) or use Register as Operator
VaultRegistrar has EXCHANGE role on DS TokenPre-configured by Securitize for the sandbox deployment
Investor has DS TokensUse the Faucet
Investor approved MockDeFiProtocol to spend DS TokensDone automatically by the sandbox UI; in code: dsToken.approve(mockProtocolAddress, amount)
EIP-712 signature is valid and unexpiredSign with the correct operator, nonce, and deadline

Adapting this pattern for your protocol

The key integration points that any DeFi protocol needs to implement:

  1. Store a vault per investor — any per-investor mapping works; the registrar only stores the vault address, not what's inside it.
  2. Call registerVault() before any DS Token transfer — the registry binding must exist before transferFrom will succeed.
  3. Use msg.sender as the operator — your contract is the operator, so the investor's EIP-712 operator field must be your contract address.
  4. Accept deadline and signature as parameters — these come from the investor's off-chain signing step and are passed through to registerVault().

For a simpler starting point (no events, no escape hatches), see Minimal Vault Factory.

Try it interactively

  • Mock Protocol Example — sandbox UI pre-wired to this contract: Sign → Approve → Deposit.
  • Protocol Tester — upload any ABI and call your own protocol contract with the same flow.