Plan for Redemption of Euler Funds

Summary

The 2023-03-13 attack on Euler extracted the majority of funds held by the protocol and converted them into ETH and DAI. Much of this has been recovered. The following is a plan for how to distribute these funds to affected users. Other options have been identified. However, after careful consideration by the Euler Foundation, Euler Labs, and external advisors, the following has been chosen as the optimum approach. This plan may be modified as the calculations progress.

This proposal addresses the mechanism for redemption. Further discussion will be needed with regards to the use of insurance funds and the Euler treasury to supplement things.

Calculations

  • For each sub-account, Euler simulates the repayment of all liabilities at the block the protocol was disabled. The on-chain oracle price (either Uniswap or Chainlink, depending on the market) as defined in the smart contract at this time is used to determine the ETH value of the assets and liabilities, and each of the account’s assets (including non-collateral assets) is proportionally used to repay the liability, assuming no slippage.
    • Self-collateralised positions are treated the same as other positions
    • Staked ETokens are handled equivalently to their underlying ETokens
    • The protocol reserves are not eligible for any redemption, and instead will be used to cover bad debt for dust accounts, and the remainder will be proportionally allocated to users
    • Markets that have bad debt in excess of reserves (a few long-tail markets that suffered oracle attacks) will have the bad debt proportionally distributed amongst depositors in the market
  • The previous step leaves each sub-account with a basket of various assets. The net asset value (NAV) of the account is computed by converting each item in the basket to ETH using a secure pricing method snapshot taken at a pre-announced future “redemption” block.
    • A subaccount with negative NAV will be considered to have a NAV of 0.
  • Each account’s NAV is computed by summing up the NAVs of each subaccount
  • Remaining balances currently held by the Euler contract will be claimable by depositors as original tokens, proportional to their deposit amounts vs total market deposits.
    • In case the remaining balances are larger than the sum of all deposits, each depositor will be able to claim the full deposited amount of tokens.
    • The value of the claimed tokens (using Euler prices as described above) will be deducted from the account’s NAV prior to the simulated repay.
  • All account NAVs will be summed to get the total NAV. Each account will be able to claim the recovered ETH, DAI, and USDC according to its proportion of the total NAV.
  • In the event that at the time of the pre-announced redemption block the value of the recovered amounts exceeds the total NAV, the excess will be distributed proportionately to users.

Mechanism

A smart contract will be created that contains the funds due to all EOAs. This contract will have a root of a merkle tree embedded. In order to claim the redemption, an EOA will need to pass in two items:

  • The claim information for the account along with a merkle proof of validity
  • A signed message and agreement that confirms that the account holder agrees with the terms of the redemption, as stipulated by the Euler Foundation

Smart Contract Accounts

There are 141 affected smart contract accounts. Redemptions can not necessarily be sent directly to smart contract accounts. Furthermore, smart contracts can not sign messages authorising their claims.

For these reasons, smart contracts will have to be handled on a case-by-case basis. Representatives of the Euler Foundation will communicate with affected protocols and smart contract wallet holders for guidance given their particular situations.

  • Wallet owners and/or representatives of protocols will need to authenticate themselves to the satisfaction of the Euler Foundation and agree to the terms of the redemption

Multi-Sig Wallets

Multi-sig wallets are a special sub-case of smart contract accounts. These wallets can be included in the merkle-based distribution contract (or a separate contract), however they will need to use a transaction in order to agree to the terms of the redemption. The contract may use the EIP-1271 standard to implement this.

Funds Recovered

Recovered funds include all those returned to the Euler DAO Treasury address following negotiations, totaling 95,556.36059211764 ETH and 43,063,729.35 DAI. Unrecovered funds at this point include funds with potential sanctions issues sent by the attacker to Tornado Cash, totaling 1,100 ETH and those sent to an address owned by the Ronin attacker, totalling 100 ETH. Another 100 ETH were returned by the attacker directly to a user, who in turn returned 12 ETH to the Euler DAO Treasury (included above). The DAO Treasury address also holds 3,396,964 USDC and 1,007,321 DAI from Sherlock protocol insurance payouts.

Dependencies

The goal is to let users redeem funds as soon as possible. For EOAs and multi-sig wallets, the following needs to happen:

  • Method for computing calculations needs to be analysed and assessed for fairness and practicality
  • Distribution contract needs to be developed and audited
  • Users need to be given sufficient time to assess their redemption status and read the terms of redemption, as well as advance notice of the redemption block number
12 Likes

Do deposits through zk.money fall under the smart contract accounts group? Asking for a friend…

3 Likes

Asking the same for my bro

This seems like a great first draft. As for the calculations, I’ve no feedback to give.

Regarding the mechanisms to claim recoverable funds:

As co-founder and core member of Mean Finance I just want to let the Euler Foundation our users have been affected by the hack through the use of our ERC4626 adapter (to generate yield on idle assets), which in turn, means they will not be able to claim from their EOAs. Whenever the Foundation starts going through the Smart Contract Accounts, please keep us and Mean Finance users in mind so we can help them get their funds back.

On funds recovered:
From what I’m interpreting there are 1100 ETH that are recoverable but due to the OFAC sanction list the Euler Foundation can not receive those? Is that right? If so, it seems that one of the solutions might be to set up a multisig by trusted anons on the ecosystem and deal with that through the tools that our ecosystem has developed, given the fact that 1100 ETH are about ~1% of stolen funds.

2 Likes

How to sign the contract if used Instadapp?

Allow people to payback their debt first in the native asset!
This would make everything fairer and easier!

Appreciate the quick and thorough look at funds redemption! :clap:t3:

Hoping for a comeback from Euler! Would be watching this closely!

1 Like

Summary

As I understand many users do not like the proposal in its current state because it leaves many borrowers that did not borrow like kind collateral with significant losses and forces them to take on positions they otherwise never would have.

Also worth noting this is an immediate look at the proposal and as more information comes out things may evolve.


My addition:

In order to avoid issues with this forced “trade” at a previously depressed price, I would suggest a small repayment window, directly to the DAO or otherwise a deposit contract controlled by the DAO.

This would allow users to close out positions naturally rather than forcing them to take on losses that are completely avoidable for ALL parties.

The result would be that the general calculation (using NAV at time of the exploit) currently in place:
Return = Supplied Value - Borrowed Value

Is slightly modified:
Return = Supplied Value(t=0) - (Borrowed Value(t=0) - Repayment Value(t=repayment))

Should the repayment window be relatively short this leaves a reasonable range for a TWAP to establish the repayment value, and given most repayment is in stables or like kind assets, variability can be expected to be minimal.

Technical Lift

Depending on how diligent the Euler team would like to be, the technical lift can be extremely small or a bit larger, and I would happily volunteer personal and DefiHedge Corporation (Swivel Finance) resources towards getting this together.

Direct repayment

The easiest / least technical lift (though not recommended) is likely to implicitly allow users to simply return capital to the DAO and to record the events of their transfers. With these events you can establish the amount of returned tokens with a pretty simple accumulation of transfers within the repayment window.

TWAP vs Precise Pricing:
With value of repaid tokens as the remaining factor, price could potentially be extracted from any number of TWAPs leaving a accurate estimate of repaid value…

That said, it should also be relatively easy to simply record the time of each transfer alongside the amount and precisely identify the value of each users repayment.

Repayment Contract

Similarly, if not comfortable accepting generalized transfers, a repayment contract that records collateral repaid per user is extremely straightforward and can provide a familiar interface for users.

Repayment Contract using Chainlink Oracles

My suggested solution would be to utilize the rails for tracking value that are already in place for Euler – Chainlink oracles.

Given all major markets (all markets now?) require chainlink oracles to function, all repayment should have chainlink oracles in place that can precisely identify the price of an asset at the time of repayment.

This then leaves a repayment contract nearly as simple as:

function repay(address asset, uint256 amount) external returns(uint256) {
           IERC20(asset).transferFrom(msg.sender, address(this), amount);
           uint256 value = amount * chainlinkConsumer.getLatestPrice(asset);
           emit Repaid(msg.sender, address, amount, value);
           return (value)
}

Conclusion

All things considered I dont really see a reason why the above proposal should NOT be put into place. As third parties we can guarantee the Euler team a precise calculation as to the repaid value, with nearly (or actually) 0 effort from the Euler team. This then makes Euler’s remaining job easy and leaves users much happier with their planned reimbursement.

I would ask for public support of the above, and if not accepted some reasonable explanations as to the issues with the proposal.

8 Likes

Agree with the proposal as is. I consider it fair and simple. Note that any proposal would always have certain number of users disagreeing and unhappy. But please note that any complicated solution would add to smart contract risk thus putting funds at risk. Also, obviously the funds are not in the form they were before hack. So, imo only the current proposal works as there would be severe complexity otherwise

1 Like

Agree with this time window solution for repayment.

Why is the value of repayment relevant, if it is basically set to zero by payment in native debt token.

1 Like

I support this amendment

It’s clear from the Discord discussion that this plan needs to be ELI5’d to produce a more meaningful discussion.

This should encompass every type of scenario and the proposed outcome. For example, pure depositors (eg, ETH), recursive borrowers, cross-asset borrowers, etc.

Great start! Me (and a lot of users) got all my Euler founds in the Aztec zkmoney… what’s the timeline in this case?

Thanks for the proposal. Given the discussions on the discord, it’s clear there are misunderstandings about how to interpret it. It would really help to have a few concrete examples. Even better would be a way to simulate the proposal on all accounts.

I have a friend that has a friend that’s wondering the same thing

I agree with the proposal. It is fair to all victims.

Some ETH depositors in discord today have misunderstood this proposal and they think their ETH deposits are being forced to be sold, which they are not.

Here is a simple example:

if you deposited 10ETH before the attack, and the ETH price was 1600 at that time. then no matter what price you go to return your deposit now, it will still be 10ETH. All values will be calculated in ETH.

For borrowers, if your health value was greater than 1 before the attack, your health value will be greater than 1 now, because the value of collateral increases during the suspension of the protocol without adding new borrowing.

2 Likes

I had more written out, but want to keep it concise since others have explained it more in depth:

Almost all users in the lending market (excluding recursive/looping activity that isn’t effected either way) are taking on a position where they consciously long collateral / short borrow

Euler users as a whole (and as is the case on all lending markets) are mostly longing non-stables (ie ETH) and shorting stables. This is reflected by where liquidity existed on Euler and which assets the exploiter stole.

Those assets were mostly not converted during the duration of the hack.

This current proposal, as I understand it, will unnecessarily negatively impact almost all users whil unnecessarily positively rewarding users who took on borrowing that is otherwise disadvantageous after the exploit began to unlock some value on their collateral (ie cbETH borrowers).

Active borrows are not affected by the hack, if users decided to convert those borrows on their own, elsewhere, they are modifying their exposure directly. If cbETH borrowers did intend to short cbETH, they would’ve sold for stablecoins on their own.

By taking two separate snapshots, most users will take a larger haircut (ETH pumped against stablecoins) while the panic borrowers and other edge cases will lock in extra profit.

I would recommend the calculation to only look at the snapshot time of redemption for both consolidation of debt and reimbursement of assets. That might translate to a small shortfall across the board, but it seems more equitable for everyone to take a small haircut than some users take a larger haircut for a position they wouldn’t have taken on in order to award other users a premium on top of, again, a position they wouldn’t have taken on.

FWIW, Rari Fuse reimbursement is the closest comparison. They did it by choosing a future reimbursement snapshot block and working off of that.

Apologies if I misunderstand the mechanics, and thanks for all the hard work team!

3 Likes

Why? There should be no one to liquidate your position at the moment.

Yep, my bad… I thought I had been liquidated before the contract was paused since I couldn’t see my eTokens in my wallet, but it looks like I didn’t… all good

Putting numbers around this. And, again, if I am misunderstood I apologize and please correct me.

Use ETH at $1,600 at time of protocol stoppage and $1,900 at time of reimbursement.

Take two positions each with $2k worth of collateral and $1k worth of debt at time of protocol stoppage:

User A: 1.25 ETH collateral 1,000 USDC borrow

Total position value: $2k / 1.25 ETH. user has 0.625 excess ETH and 1,000 USDC in wallet

ETH goes up to $1,900

Total position value: $2,375 / 1.25 ETH. user has 0.72~ excess ETH and 1,000 USDC in wallet

User B: 2,000 USDC collateral 0.625 ETH borrow

Total position value: $2k / 1.25 ETH. user has 1,000 excess USDC and 0.625 ETH in wallet

ETH goes up to $1,900

Total position value: $2,000 / 1.05~ ETH. User has $100 excess USDC and 1 ETH in wallet

User A is exposed to ETH profit. User B is not negatively impacted unless they sold the ETH on their own (outside of the lending market, and not relevant).

This proposed model maintains that each has a net position value of $1,000 (in both cases, $2k worth of deposits and $1k worth of borrows. Assumes ETH is worth $1,600).

This results in User A and user B both receiving ~0.526 ETH

User A’s total position after reimbursement is 1,000 USDC + 0.526 ETH => Worth $2,000 / $2,375 = 16% haircut

User B’s total position after reimbursement is 0.625 ETH + 0.526 ETH => Worth $2,187 / $2,000 = 9% premium

If debt is consolidated at the same block that reimbursement is calculated, then both users have no haircut/premium (assuming protocol can cover 100%).

Note per the last section, that under the current model, there will likely be a surplus that gets distributed proportionately. So the haircut/premium for User A and User B looks like X%-16% and X%+9%, respectively

8 Likes