<style>
.reveal {
font-size: 24px;
}
.two-columns {
display: flex;
}
.col {
flex: 1;
}
.tomorrow-comment, pre .comment, pre .title {
color: #8e908c;
}
.tomorrow-red, pre .variable, pre .attribute, pre .tag, pre .regexp, pre .ruby .constant, pre .xml .tag .title, pre .xml .pi, pre .xml .doctype, pre .html .doctype, pre .css .id, pre .css .class, pre .css .pseudo {
color: #c82829;
}
.tomorrow-orange, pre .number, pre .preprocessor, pre .built_in, pre .literal, pre .params, pre .constant {
color: #f5871f;
}
.tomorrow-yellow, pre .class, pre .ruby .class .title, pre .css .rules .attribute {
color: #eab700;
}
.tomorrow-green, pre .string, pre .value, pre .inheritance, pre .header, pre .ruby .symbol, pre .xml .cdata {
color: #718c00;
}
.tomorrow-aqua, pre .css .hexcolor {
color: #3e999f;
}
.tomorrow-blue, pre .function, pre .python .decorator, pre .python .title, pre .ruby .function .title, pre .ruby .title .keyword, pre .perl .sub, pre .javascript .title, pre .coffeescript .title {
color: #4271ae;
}
.tomorrow-purple, pre .keyword, pre .javascript .function {
color: #8959a8;
}
.reveal pre code {
display: block;
background: white;
color: #4d4d4c;
font-family: Menlo, Monaco, Consolas, monospace;
line-height: 1.5;
border: 1px solid #ccc;
padding: 10px;
}
</style>
# Smart Contract Upgradeability in DeFi protocols
### Daniel Perez and Paul Pritz
#### Imperial College London
<!-- Put the link to this slide here so people can follow -->
---
## Immutability vs Flexibility
- Ethereum is immutable by default
- Protocols use specific design patterns to work around this to be maintainable in practice
- This leads to several risks as functionality can be changed
<img width="80%" alt="Immutable contract" src="https://i.imgur.com/xdEIBUt.png">
---
# Proxy Pattern
- The EIP 1822 proxy pattern is commonly used to allow upgradeability
- This works by delegate calling functions in another contract that can be exchanged
<img width="80%" alt="Immutable contract" src="https://i.imgur.com/MTZvrLN.png">
---
# Contract Setting Pattern
- This works by splitting functionality in an entry point and a logic contract
- The address of the logic contract can be set and changed
- This offers more control as not everything is exchangeable but also limits flexibility
<img width="80%" alt="Immutable contract" src="https://i.imgur.com/dSqklXC.png">
---
# Governance and Upgradeability
- Upgrades are executed by some governance mechanims
- Typically two patterns exist: On-chain voting or a multisig with optional off-chain voting
- Timelocks are used to allow users to react to changes - trade-off between being able to react to problems and risk for users not being able to react to changes
- Trade-off between gate-keeper function of multisig and trust requirement
---
# Taxonomy
- If large parts of a protocol are upgradeable, the barrier to executing upgrades should be high
<img width="80%" alt="Immutable contract" src="https://i.imgur.com/SB8TK6q.png">
---
## Automating Upgradeability Detection
The tool scans contracts for upgradeability using the EIP 1822 pattern:
- By convention, EIP 1822 stores the address of the logic contract in a specific storage slot
- The tool analyses the bytecode to detect whether this solt has been set
- The contract setting pattern and patterns deviating from EIP 1822 are harder to detect as these differ across protocols
- The tool also checks for common proxy pattern functions such as `implementation()`
---
## Proxy Pattern Upgradeable Contracts
| Protocol | Scanned | Upgradeable | Percentage |
|------------|-----------|---------------|--------------|
| Aave | 50 | 39 | 78.00% |
| MakerDAO | 278 | 10 | 3.60% |
| Curve | 111 | 1 | 0.90% |
| Convex | 33 | 0 | 0.00% |
| Compound | 72 | 36 | 50.00% |
---
# Case Study #1: Compound
- Everything upgradeable (proxy pattern), everything goes through on-chain governance
- Time locks are enforced (currently 2 days)
- Reliance on voters to review and understand proposals
- Timelocks meant that they couldn't immediately react: $90m funds lost
```solidity
if (supplierIndex == 0 && supplyIndex > compInitialIndex) {
supplierIndex = compInitialIndex;
}
Double memory deltaIndex = Double({
mantissa: sub_(supplyIndex, supplierIndex)});
uint supplierTokens = CToken(cToken).balanceOf(supplier);
uint supplierDelta = mul_(supplierTokens, deltaIndex);
```
---
# Case Study #2: MakerDAO
<div class="two-columns">
<div class="col">
<ul>
<li>Everything upgradeable (contract setting pattern), everything goes through on-chain governance</li>
<li>Time locks employed (24h)</li>
<li>Poor voting design (no lock period) led to flash loan attack on voting mechanism</li>
<li>No monetary consequences as attacker only whitelisted a coin - but could have led to loss of all funds [1] </li>
</ul>
</div>
<div class="col">
<img alt="Flash loan proteciton" src="https://i.imgur.com/ghHk9h3.png" width="500px">
</div>
</div>
<div style="margin-top: 3em; font-size: 1.2rem">
[1] Gudgeon, Lewis, et al. "The decentralized financial crisis." 2020 Crypto Valley Conference on Blockchain Technology (CVCBT). IEEE, 2020.
</div>
---
# Case Study #3: Convex
- Almost nothing upgradeable, except for StakingProxy (which holds almost all vote locked CVX) through contract setting pattern
```solidity
function setStakingContract(address _staking) external onlyOwner {
require(stakingProxy == address(0) || (minimumStake == 0 && maximumStake == 0), "!assign");
stakingProxy = _staking;
}
```
- Upgrade executable by multisig without time delay, all 1.5B USD worth of CVX could have been stolen in single transaction
- This has now been fixed in a V2 version of the ConvexLocker
```python
ConvexLocker cvxLocker;
CvxStakingProxy stakingProxy;
cvxLocker.setStakeLimits(0, 0, {"from": multisig});
cvxLocker.setStakingContract(stakingProxy, {"from": multisig});
cvxLocker.setStakeLimits(1, 1, {"from": multisig});
```
---
# Conclusion
- Our tool shows that many protocols are not actually fully immutable
- Upgradeability is a necessary evil to allow protocols to be maintained
- Protocols with extensive upgradeability should put barriers to upgrade execution in place (efficient frontier)
{"metaMigratedAt":"2023-06-16T23:35:10.136Z","metaMigratedFrom":"YAML","title":"Smart Contracts Upgradeability in DeFi protocols","breaks":true,"description":"Slides for FC22 DeFi workshop","slideOptions":"{\"theme\":\"white\"}","contributors":"[{\"id\":\"3f4fe1bb-6fd5-400f-b366-e0b40bf7913e\",\"add\":5150,\"del\":2511},{\"id\":\"53025b32-e778-4a7a-ba5f-3e8ab5cefb3a\",\"add\":6504,\"del\":2543}]"}