# Smart Contracts
A technical overview of all smart contracts powering the Decentralized Euro protocol.
The Decentralized Euro protocol consists of multiple smart contracts that work together to create a trustless, oracle-free stablecoin system. All contracts are deployed on Ethereum mainnet and are fully immutable - no admin keys, no upgrades, no central control.
# Contract Architecture
The contracts are organized into the following categories:
| Category | Purpose |
|---|---|
| Core | Token contracts and reserve management |
| MintingHub | Position management and collateralized minting |
| Savings | Interest-bearing dEURO deposits |
| Bridges | 1:1 conversion with trusted external EUR stablecoins |
| Gateways | Frontend rewards and enhanced functionality (V2 only) |
# Protocol Modules: V2 and V3
The dEURO contracts are immutable and cannot be replaced. Instead of upgrading via proxies, the protocol evolves by adding new modules through the standard suggestMinter() governance flow. The protocol currently runs two coexisting MintingHub and Savings module sets on Ethereum mainnet:
| Module | Status | Frontend Rewards | Notes |
|---|---|---|---|
| V2 | Active, permanent | Yes (via Gateways) | Original launch modules; positions and savings opened here remain fully usable. Cannot be deactivated. Includes the CoinLendingGateway for native ETH lending. |
| V3 | Active, permanent | No | Additional module set approved by nDEPS governance. Adds an updated savings/vault design and a price reference system. Routes do not pass through FrontendGateway. |
Both module sets share the same dEURO token, the same nDEPS / DEPSwrapper governance pair, and the same Bridge contracts. New positions and savings deposits can be opened in either module; existing V2 positions are not migrated and continue to live under V2.
TIP
V3 is not a replacement for V2. It is an additional, parallel set of minter contracts that nDEPS holders approved through the standard governance application period. V2 remains the only home for positions and savings that were opened before V3 went live.
# Core Contracts
# Decentralized Euro (dEURO)
The main stablecoin token contract - an ERC-20 token designed to track the value of the Euro.
Key Features:
- Implements ERC-20 and ERC-2612 (Permit)
- Open to arbitrary minting plugins with veto-based governance
- Creates the Equity contract during deployment
- Manages the minter registry and position registry
- Handles reserve accounting and loss coverage
Key Functions:
suggestMinter()- Propose a new minting contract (requires fee and application period)denyMinter()- Qualified shareholders can veto minting proposalsmintWithReserve()- Mint dEURO with reserve contribution (minters only)burnFromWithReserve()- Burn dEURO and reclaim proportional reserve
| Property | Value |
|---|---|
| Symbol | dEURO |
| Decimals | 18 |
| Min Application Period | 14 days |
| Min Application Fee | 1,000 dEURO |
| Address | 0xbA3f535bbCcCcA2A154b573Ca6c5A49BAAE0a3ea (opens new window) |
# Equity (nDEPS)
The native equity token representing shares in the dEURO reserve pool. Holding nDEPS is similar to being a shareholder of a bank.
Key Features:
- ERC-20 token with time-weighted voting power
- 2% quorum required for governance veto
- Price determined by proportional capital valuation (5x equity)
- 2% fee on minting and redemption
- 90-day minimum holding period before redemption is permitted (replaces the same-block redemption guard used in Frankencoin — the holding period subsumes the flash-loan attack surface)
Key Functions:
invest()- Mint nDEPS by depositing dEURO into the reserveredeem()- Burn nDEPS to withdraw dEURO from the reservecheckQualified()- Verify if an address has sufficient voting power (2%)delegateVoteTo()- Delegate voting power to another addresskamikaze()- Sacrifice own votes to reduce malicious actor's votes
Voting Mechanics:
- Votes accumulate over time:
votes = balance * holdingDuration - Longer holding = more voting power
- Delegation adds to delegate's power without removing own votes
| Property | Value |
|---|---|
| Symbol | nDEPS |
| Decimals | 18 |
| Valuation Factor | 5x (market cap = 5 × equity) |
| Quorum | 2% |
| Min Holding Duration | 90 days |
Min Application Period (for suggestMinter) | 14 days |
| Min Application Fee | 1,000 dEURO |
| Min Equity | 1,000 dEURO |
| Address | 0xc71104001A3CCDA1BEf1177d765831Bd1bfE8eE6 (opens new window) |
# DEPSwrapper (DEPS)
A standalone ERC-20 wrapper around nDEPS. Wrapping nDEPS into DEPS exchanges the voting/holding mechanics for free transferability:
- nDEPS carries time-weighted voting power and resets the holding clock on every transfer.
- DEPS is a plain ERC-20: transfer freely, hold custodially, deposit in AMMs, but no voting power until unwrapped.
- Wrapping is 1:1 in both directions; the wrapper never touches the underlying economic value.
function wrap(uint256 amount) public
function unwrap(uint256 amount) public
function unwrapAndSell(uint256 amount) public returns (uint256) // unwrap and immediately redeem via Equity
function halveHoldingDuration(address[] helpers) public // anti-vote-accumulation, requires 2% votes
unwrapAndSell() is provided as a convenience for redeeming directly into dEURO without first claiming the nDEPS to the caller's address. It bypasses the 90-day holding period of the underlying nDEPS as long as the wrapper itself has held them long enough on average and halveHoldingDuration() has not been called recently. Wrapping nDEPS into DEPS keeps the holding clock of the underlying nDEPS intact; unwrapping back to nDEPS, however, resets the recipient's holding clock as with any other transfer.
| Property | Value |
|---|---|
| Symbol | DEPS |
| Decimals | 18 |
| Address (Mainnet) | 0x103747924E74708139a9400e4Ab4BEA79FFFA380 (opens new window) |
| Address (Base) | 0x5F674bF6d559229bDd29D642d2e0978f1E282722 (opens new window) |
# MintingHub Contracts
# MintingHub
The central hub for creating, cloning, and challenging collateralized dEURO positions.
Key Features:
- Creates new position contracts via PositionFactory
- Manages Dutch auctions for liquidations
- Handles forced sales of expired positions
Key Functions:
openPosition()- Create a new collateralized position (1,000 dEURO fee)clone()- Clone an existing position with new parameterschallenge()- Start a Dutch auction to challenge undercollateralized positionsbid()- Place a bid in an ongoing challenge auctionbuyExpiredCollateral()- Purchase collateral from expired positions
Challenge Process:
- Phase 1 (Aversion): Position owner can avert by buying challenger's collateral at liquidation price
- Phase 2 (Auction): Dutch auction where price decreases linearly to zero
| Property | Value |
|---|---|
| Opening Fee | 1,000 dEURO |
| Challenger Reward | 2% |
| Min Challenge Period | 1 day |
The protocol exposes two MintingHub modules. V2 is wrapped by MintingHubGateway for frontend-code tracking; V3 routes directly through MintingHub and adds an updated savings/vault design.
| Module | Address |
|---|---|
V2 (MintingHubGateway) | 0x8B3c41c649B9c7085C171CbB82337889b3604618 (opens new window) |
V3 (MintingHub) | 0x66AcC54a0C64255137b8993CB4972B0901684f7B (opens new window) |
# Position
Individual collateralized debt position contract. Each position is a separate contract holding the user's collateral.
Key Features:
- Immutable parameters set at creation (collateral type, reserve ratio, etc.)
- Continuous interest accrual based on Leadrate + risk premium
- Cooldown periods on price increases (3 days) for security
- Can be denied by governance during initialization period
Key Functions:
mint()- Mint dEURO against deposited collateralrepay()- Repay debt (interest first in V3, then principal)adjust()- All-in-one function to modify position parametersadjustWithReference()(V3) - Same asadjust()but accepts a reference position that can waive the 3-day cooldown on a price increaseadjustPrice()/adjustPriceWithReference()(V3) - Change the liquidation price, optionally with a reference positionwithdrawCollateral()/withdrawCollateralAsNative()(V3) - Withdraw excess collateral (native ETH variant available in V3)deny()- Governance can deny positions during the init period
Interest Model:
Interest accrues continuously in both V2 and V3 — the up-front fee charged at mint time was a V1 (Frankencoin) characteristic that dEURO removed at launch. In both versions, principal and interest are tracked separately on the Position contract, and adjust(newPrincipal, …) lets owners change principal independently of the outstanding interest.
V3 changed the following relative to V2:
- Native ETH/WETH is supported directly across
MintingHub,PositionandPositionRoller(V2 needs the CoinLendingGateway for the same). - Leadrate is integrated into MintingHub itself, so positions and savings consume the same rate source (V2 inherited Leadrate via
Savings → SavingsGateway). - Interest is charged only on the usable mint (principal minus the part held back in the borrowers reserve), not on the full minted amount.
- Reference positions can be passed to
adjust*WithReference()to skip the 3-day cooldown on a price increase when another live position has already validated a higher price.
| Property | Value |
|---|---|
| Deployment | Via PositionFactory (ERC-1167 clones) |
| Cooldown on Price Increase | 3 days (V3: waivable via reference position) |
| Min Position Init Period | 3 days (V2 and V3) |
| Rate base | Leadrate at mint time + risk premium, re-synced to Leadrate whenever new tokens are minted into the position |
| Reference Position Mechanism (V3) | adjustWithReference() / adjustPriceWithReference() accept a sibling position to skip cooldown when the new price is already validated elsewhere |
# PositionFactory
Factory contract for deploying new Position contracts using the ERC-1167 minimal proxy pattern.
Key Features:
- Creates new positions with full parameter set
- Clones existing positions efficiently using minimal proxy
- Validates position parameters before cloning
Key Functions:
createNewPosition()- Deploy a completely new position contractclonePosition()- Create a minimal proxy clone of an existing position
Each MintingHub module owns its own PositionFactory.
| Module | Address |
|---|---|
| V2 | 0x167144d66AC1D02EAAFCa3649ef3305ea31Ee5A8 (opens new window) |
| V3 | 0x3a3985a96b1B51E6d914bc7C9e89fD6Ba6dEfE81 (opens new window) |
# PositionRoller
Helper contract for rolling over debt from one position to another using flash loans.
Key Features:
- Atomically moves debt and collateral between positions
- Uses flash loans to avoid needing upfront capital
- Preserves frontend codes when rolling through gateways
Key Functions:
roll()- Roll debt from source to target position with custom parametersrollFully()- Roll entire position automatically
A PositionRoller can only roll between positions inside the same MintingHub module.
| Module | Address |
|---|---|
| V2 | 0x4CE0AB2FC21Bd27a47A64F594Fdf7654Ea57Dc79 (opens new window) |
| V3 | 0x5C22d5b752b2121faE7F6f0069252B03B2F7c5CD (opens new window) |
# Savings Contracts
# Savings
Base savings module that enables interest-bearing dEURO deposits based on the Leadrate.
Key Features:
- Interest accrues continuously based on Leadrate
- No lockup period - withdraw anytime
- Interest paid from system equity (profits)
- Disabled when interest rate is zero
Key Functions:
save()- Deposit dEURO into savingswithdraw()- Withdraw dEURO and accrued interestrefreshBalance()- Collect accrued interest into balanceadjust()- Adjust savings to target amount
The protocol exposes two Savings modules. V2 is wrapped by SavingsGateway for frontend-code tracking; V3 routes directly through Savings and skips the FrontendGateway layer.
| Module | Address |
|---|---|
V2 (SavingsGateway) | 0x073493d73258C4BEb6542e8dd3e1b2891C972303 (opens new window) |
V3 (Savings) | 0x760233b90e45d186A9A98E911B115F7F4B90d3D9 (opens new window) |
# SavingsVault (svDEURO)
ERC-4626 compatible vault adapter for the Savings module.
Key Features:
- Standard vault interface for DeFi composability
- Automatic interest accrual on deposits/withdrawals
- Protected against inflation attacks via virtual shares
- Tracks total claimed interest
Key Functions:
deposit()- Deposit dEURO and receive vault shareswithdraw()- Burn shares and receive dEURO with interestprice()- Current price per sharetotalAssets()- Total dEURO including accrued interest
| Property | Value |
|---|---|
| Symbol | svDEURO |
| Standard | ERC-4626 |
Each Savings module ships with its own SavingsVault adapter.
| Module | Address |
|---|---|
| V2 | 0x1e9f008B1C538bE32F190516735bF1C634B4FA40 (opens new window) |
| V3 | 0x75Beb37A3C86eE4c38931E2a9319E078da612979 (opens new window) |
# Leadrate
The governance-controlled base interest rate of the system. Leadrate is an abstract base contract: in V2 it is inherited via Savings → SavingsGateway, and in V3 the V3 MintingHub inherits it directly so positions and savings consume the same rate.
Key Features:
- Qualified nDEPS holders can propose rate changes
- 7-day timelock on all rate changes
- Tracks accumulated "ticks" for interest calculations
- Used by both Savings and Position contracts
Key Functions:
proposeChange(uint24 newRatePPM, address[] helpers)- Propose a new interest rate (requires 2% voting power)applyChange()- Execute a pending rate change after 7 dayscurrentTicks()- Get accumulated interest ticks since deployment
| Property | Value |
|---|---|
| Rate Format | PPM (parts per million) per year |
| Timelock | 7 days |
| Initial V2 rate | 10% (100000 PPM) |
| Initial V3 rate | 8% (80000 PPM) |
# Bridge Contracts
# StablecoinBridge
Enables 1:1 conversion between trusted external EUR stablecoins and dEURO.
Key Features:
- Mints dEURO by depositing source stablecoins
- Burns dEURO to retrieve source stablecoins
- Has maximum limit and expiration horizon
Key Functions:
mint()- Convert source stablecoin to dEUROburn()- Convert dEURO back to source stablecoin
# EUR Stablecoin Bridges
Bridges whose horizon has passed are expired: minting reverts, burning dEURO back into the underlying stablecoin keeps working. Status as of the on-chain horizon() values (see Swap for details):
# Gateway Contracts
V2 ONLY
The Gateway layer only exists in V2. V3 modules (MintingHub, Savings) bypass the Gateway pattern entirely and do not emit frontend rewards. Frontend operators only earn rewards on V2 activity.
# FrontendGateway
Manages frontend referral codes and distributes rewards to frontend operators.
Key Features:
- Frontend operators register unique codes
- Rewards distributed based on user activity
- Covers investments, savings, and minting
- Governance-controlled fee rates with 7-day timelock
Key Functions:
registerFrontendCode()- Register a new frontend codeinvest()- Invest in nDEPS with frontend rewardredeem()- Redeem nDEPS with frontend rewardwithdrawRewards()- Claim accumulated frontend rewardsproposeChanges()- Propose new fee rates (requires 2% votes)
| Activity | Rate |
|---|---|
| Investment / Redemption | 1% of volume |
| Savings interest | 5% of interest earned |
| Minting interest | 5% of interest paid |
| Property | Address |
|---|---|
| Mainnet | 0x5c49C00f897bD970d964BFB8c3065ae65a180994 (opens new window) |
# CoinLendingGateway
The V2 minting hub only accepts ERC-20 collateral. To open a leveraged position backed by native ETH without first wrapping it manually, the CoinLendingGateway (V2 only) takes ETH via msg.value, wraps it to WETH internally, clones a parent WETH position, and transfers ownership to the user. It also exposes a price-adjusted clone flow for setting a custom liquidation price in the same transaction.
Key Features:
- Accepts native ETH directly (no manual WETH wrapping)
- Clones the parent position and transfers ownership atomically
- Optionally adjusts the liquidation price during clone (price adjustment in the same tx)
- Routes through
MintingHubGateway, so frontend codes are preserved
V3 has no equivalent: the V3 MintingHub and PositionRoller support native ETH directly via their *Native variants and payable functions, removing the need for a separate gateway.
| Property | Address |
|---|---|
| Mainnet (V2 only) | 0x1DA37D613FB590eeD37520b72e9c6F0F6eee89D2 (opens new window) |
# Contract Summary
# Shared
| Contract | Address | Purpose |
|---|---|---|
| dEURO | 0xbA3f...3ea (opens new window) | Main stablecoin token |
| nDEPS (Equity) | 0xc711...EE6 (opens new window) | Reserve pool shares with voting |
| DEPS (Wrapper) | 0x1037...380 (opens new window) | Transferable wrapper for nDEPS |
# V2 Module (active, with frontend rewards)
| Contract | Address | Purpose |
|---|---|---|
| MintingHubGateway | 0x8B3c...618 (opens new window) | Position management hub (V2) |
| PositionFactory | 0x1671...5A8 (opens new window) | Position deployment factory (V2) |
| PositionRoller | 0x4CE0...c79 (opens new window) | Position rollover helper (V2) |
| SavingsGateway | 0x0734...303 (opens new window) | Savings with frontend rewards |
| SavingsVault | 0x1e9f...A40 (opens new window) | ERC-4626 savings vault (V2) |
| FrontendGateway | 0x5c49...994 (opens new window) | Frontend reward system (V2 only) |
| CoinLendingGateway | 0x1DA3...9D2 (opens new window) | Native ETH lending gateway (V2 only) |
# V3 Module (active, no frontend rewards)
| Contract | Address | Purpose |
|---|---|---|
| MintingHub | 0x66Ac...4f7B (opens new window) | Position management hub (V3) |
| PositionFactory | 0x3a39...FE81 (opens new window) | Position deployment factory (V3) |
| PositionRoller | 0x5C22...c5CD (opens new window) | Position rollover helper (V3) |
| Savings | 0x7602...d3D9 (opens new window) | Savings module (V3) |
| SavingsVault | 0x75Be...2979 (opens new window) | ERC-4626 savings vault (V3) |
# Layer 2 Deployments
dEURO is canonically minted on Ethereum mainnet. Bridged token contracts mirror the supply on Layer 2 networks via the OP Stack standard bridge (0x4200000000000000000000000000000000000010). See Bridge to other Chains for the bridging UX.
| Chain | Token | Address |
|---|---|---|
| Optimism | dEURO | 0x1B5F7fA46ED0F487F049C42f374cA4827d65A264 (opens new window) |
| Base | dEURO | 0x1B5F7fA46ED0F487F049C42f374cA4827d65A264 (opens new window) |
| Base | DEPS | 0x5F674bF6d559229bDd29D642d2e0978f1E282722 (opens new window) |
# Security Properties
The dEURO smart contracts are designed with the following security properties:
| Property | Implementation |
|---|---|
| Immutability | No admin keys, no proxy upgrades |
| Oracle-free | No reliance on external price feeds |
| Flash loan protection | 90-day minimum holding period on nDEPS makes flash-loan governance attacks impossible |
| Governance timelocks | 7-14 day delays on critical changes |
| Minority protection | 2% veto threshold |
| Bridge expiry | Every bridge winds down automatically at its horizon |
| Inflation attack mitigation | ERC-4626 virtual shares pattern |
# Source Code
All smart contract source code is available on GitHub:
Repository: github.com/d-EURO/smartContracts (opens new window)
| Network | Chain ID | Explorer |
|---|---|---|
| Ethereum Mainnet | 1 | etherscan.io (opens new window) |
| Base | 8453 | basescan.org (opens new window) |
| Optimism | 10 | optimistic.etherscan.io (opens new window) |
# Complete Function Reference
For a comprehensive listing of every public function across all contracts — full signatures, parameters, return values, events — see the Smart Contract Functions Reference.