2.1.0 - Compliance checks

New features for pooled staking integration contract and how to opt-in to this version

circle-check

Upgrade content: 2.1.0 - Compliance checks

To strengthen sanctions-compliance controls, we have introduced a lightweight upgrade to the Native20 (integrator) contract. With this version you will be able to enforce onchain OFAC oracle checks and manage an allowlist/blocklist with granular action management.

New features:

(Opt-in) Activate OFAC screening:

  • New depositors can't interact with your integrator contract if they are on the OFAC sanctionned list

  • User that is invested in the product and get sanctionned (part of the OFAC sanctionned list) can't withdraw their funds

1. Introduction

Each Native20 deployment is a TUPProxy (Transparent Upgradeable Pausable Proxy) aka integration contract. The proxy holds all user state (balances, approvals, pool config). The implementation contract holds the logic. Upgrading swaps the logic without touching user state.

This upgrade introduces AccountList rights enforcement. This means that after upgrade, users need default rights set to be able to stake and request exits. If you only call upgradeTo(), users will be locked out until setDefaultRights() is called separately by the admin, this mean we must have access to both admins in order to perform the upgrade.

Key actors involved in the upgrade:

Role
What it does
How to find it

Proxy Admin

Can call upgradeTo()

Stored in the proxy's ERC1967 admin slot

Integration Admin

Can call setDefaultRights()

Stored in the contract's $admin slot, readable via admin()

These are usually not the same address. The upgrade itself requires the proxy admin. Setting default rights requires the integration admin.


2. Prerequisites

You need:

  • Foundry installed (forge, cast)

  • An Ethereum RPC endpoint (Infura, Alchemy, or your own node)

  • The proxy admin private key or access to the multisig that controls each proxy

  • The integration admin private key or access to the multisig that can call setDefaultRights

Set your RPC URL:


3. Understanding the Architecture

Each Native20 deployment looks like this:

Key ERC1967 storage slots:

Slot
Contents

0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc

Implementation address

0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103

Proxy admin address

Rights bit values (defined in MultiPool.sol):

Right
Hex
Decimal
Bit

FORBIDDEN

0x1

1

0

STAKE

0x2

2

1

TRANSFER

0x4

4

2

REQUEST_EXIT

0x8

8

3

The default rights value you want for normal operation is STAKE | REQUEST_EXIT = 0xA (decimal 10). This sets the rights to be iso with the behavior before the upgrade.


4. Identifying Proxy Admin Addresses

First we set our target contract address as environment variable:

Read the admin from the ERC1967 storage slot:

Read the current implementation address:

To read the integration admin (the one that can call setDefaultRights):

circle-info

Alternatively you can also check theses values in Etherscan.


Before upgrading, it's a good idea to record the current state to perform a quick sanity check after the upgrade. This includes:

  • Rate (cast call $PROXY_ADDRESS 'rate()(uint256)')

  • Total supply (cast call $PROXY_ADDRESS 'totalSupply()(uint256)')

  • Total underlying supply (cast call $PROXY_ADDRESS 'totalUnderlyingSupply()(uint256)')

6. Performing the Upgrade

The new implementation contract was deployed and verified by Kiln at the following address: 0xE0e27f00E7455188E93F6afFcbf82b15c7d4E871arrow-up-right. You can check the source code on Etherscan to verify it matches the expected implementation.

upgradeTo() + setDefaultRights() (Two transactions mandatory)

Step 1 and 2 must be done in order and should be done as close together as possible to minimize disruption. Users will be unable to stake or request exits between the two steps.

Step 1 — Upgrade (requires proxy admin):

Step 2 — Set default rights no OFAC screening (requires integration admin):

Step 3 (optional) — Enable OFAC sanctioned screening (requires integration admin):

circle-info

Note that if this feature is enabled OFAC wallet can't deposit more and OFAC sanctionned wallet will never be able to withdraw from the contract.

If using multisig (e.g., Gnosis Safe)

Start by creating both proposals (upgrade and set rights) in the multisig interface, bring them all to n-1 signatures, and get the last quorum members together to execute them back-to-back.

Step by step:

  1. With the proxy admin multisig, create a transaction to call upgradeTo(new_impl) on the proxy address.

  2. With the integration admin multisig, create a second transaction in to call setDefaultRights(10) on the proxy address.

  3. Get all the necessary signatures but 1 on both transactions.

  4. Coordinate the last signers on both multisig. First perform the last signature and execute the upgrade proposal, once done do the last signature and execute the set rights transaction as soon as possible.


7. Post-Upgrade Verification

After each upgrade, verify:

7.1 Implementation changed

7.2 Default rights are set

7.3 Basic view functions still work and return expected values

7.4 Rate is preserved

The rate should be the same as before upgrade. If you recorded the rate before:

7.5 Staking works (optional, on a test fork)

On a mainnet fork, verify a fresh user can stake:


APPENDIX : Verifying the upgrade on a local fork first

Always test on a mainnet fork before executing on mainnet:

In another terminal you can the following bash commands, replacing the PROXY_ADDRESS with your target

Need help ?

If you need assistance to perform the upgrade of if you have questions, please reach out to our support team.

Last updated

Was this helpful?