Skip to content

Commit

Permalink
πŸ‘· Odos integration (#56)
Browse files Browse the repository at this point in the history
* πŸ‘· wip odos swap

* forge install: surl

* βš™οΈ add ffi to foundry.toml

* πŸ‘· added odos router to zap constructor

* βœ… successful odos quote using SURL

* βœ… arb quote test and fmt

* βœ… successfully calling odosAssemble

* βœ… wip odos testing

* ✨ Lint

* βœ… blocked on testing

* βœ… test failing in the odos swap

* βœ… latest block on base fixed odos test

* βœ… swap for tests + docs

* βœ… asserts on swap for tests

* βœ…  fork tests take current block

* ✨ removed all uniswap logic / mentions, renamed odos vars, updated docs

* πŸ‘· replaced ternary logic in unwind

* ✨ removed unused constants

* ✨ fmt

* πŸ“š docs + fmt

* ✨ renamed swapFrom test

* fmt

* βœ… added new bootstrap with current block forking

* ✨ fmt

* burn test

* ✨fmt

* πŸ‘· fix: odos unwind swap return (#57)

* πŸ‘· fix: odos unwind swap return

* fix

* ✨ fmt

---------

Co-authored-by: Moss <moss@cc.snxdao.io>

* πŸ‘·πŸ»β€β™‚οΈ Odos refund + Unwind Test (#58)

* πŸ‘· refund logic

* βœ… unwind test

* πŸ‘· Odos audit fix (#59)

* πŸ“š first round of fixes

* πŸ‘· fix 2

* some test fixes

* πŸ‘· fix leftovers (#60)

* πŸ‘· fix leftovers

* fmt

---------

Co-authored-by: Moss <moss@cc.snxdao.io>

* audit remidiations 23/11

* πŸ‘· zapOut when unwinding USDC (#64)

* πŸ‘· zapOut when unwinding USDC

* fix make deploy_base

* πŸ‘· adjust minAmountOut to match usdc 6 decimal precision when unwinding udsc

* πŸ‘· test fix

* ✨ fmt
  • Loading branch information
moss-eth authored Dec 5, 2024
1 parent 356a455 commit c8292c5
Show file tree
Hide file tree
Showing 37 changed files with 2,905 additions and 701 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "lib/surl"]
path = lib/surl
url = https://github.com/memester-xyz/surl
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

## Overview

Zap is a smart contract that facilitates stablecoin "zapping" and Synthetix native collateral unwinding by integrating flash loans from Aave and Uniswap v3 swaps.
Zap is a smart contract that facilitates stablecoin "zapping" and Synthetix native collateral unwinding by integrating flash loans from Aave and Odos swaps.

### What is a **Zap**?

Expand All @@ -29,7 +29,7 @@ USDC <--(spot market)--> sUSDC <--(spot market)--> USDx
2. **Zap into USDx (Synthetix Spot Market):** Use the borrowed funds to zap into USDx.
3. **Burn USDx & Repay Debt (Synthetix Core):** Repay Synthetix debt by burning USDx.
4. **Withdraw and Unwrap Collateral (Synthetix Spot Market):** Withdraw margin (e.g., sETH) and convert it back to underlying assets (e.g., WETH).
5. **Swap (Uniswap):** Exchange collateral assets (like WETH) for USDC to repay the flash loan.
5. **Swap (Odos):** Exchange collateral assets (like WETH) for USDC to repay the flash loan.
6. **Flash Loan Repayment (Aave):** The USDC loan, including the premium, is repaid to Aave.
7. **Send Remaining Collateral (Synthetix):** Any surplus collateral is returned to the user.

Expand All @@ -38,10 +38,10 @@ USDC <--(spot market)--> sUSDC <--(spot market)--> USDx
- Zap via Synthetix
- Wrap & Unwrap Collateral via Synthetix
- Buy & Sell via Synthetix
- Unwind Collateral via Synthetix, Aave, and Uniswap
- Unwind Collateral via Synthetix, Aave, and Odos
- Burn Debt via Synthetix
- Withdraw Perp Collateral via Synthetix
- Swap via Uniswap
- Swap via Odos

## Development

Expand Down
8 changes: 4 additions & 4 deletions docs/src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

## Overview

Zap is a smart contract that facilitates stablecoin "zapping" and Synthetix native collateral unwinding by integrating flash loans from Aave and Uniswap v3 swaps.
Zap is a smart contract that facilitates stablecoin "zapping" and Synthetix native collateral unwinding by integrating flash loans from Aave and Odos swaps.

### What is a **Zap**?

Expand All @@ -29,7 +29,7 @@ USDC <--(spot market)--> sUSDC <--(spot market)--> USDx
2. **Zap into USDx (Synthetix Spot Market):** Use the borrowed funds to zap into USDx.
3. **Burn USDx & Repay Debt (Synthetix Core):** Repay Synthetix debt by burning USDx.
4. **Withdraw and Unwrap Collateral (Synthetix Spot Market):** Withdraw margin (e.g., sETH) and convert it back to underlying assets (e.g., WETH).
5. **Swap (Uniswap):** Exchange collateral assets (like WETH) for USDC to repay the flash loan.
5. **Swap (Odos):** Exchange collateral assets (like WETH) for USDC to repay the flash loan.
6. **Flash Loan Repayment (Aave):** The USDC loan, including the premium, is repaid to Aave.
7. **Send Remaining Collateral (Synthetix):** Any surplus collateral is returned to the user.

Expand All @@ -38,10 +38,10 @@ USDC <--(spot market)--> sUSDC <--(spot market)--> USDx
- Zap via Synthetix
- Wrap & Unwrap Collateral via Synthetix
- Buy & Sell via Synthetix
- Unwind Collateral via Synthetix, Aave, and Uniswap
- Unwind Collateral via Synthetix, Aave, and Odos
- Burn Debt via Synthetix
- Withdraw Perp Collateral via Synthetix
- Swap via Uniswap
- Swap via Odos

## Development

Expand Down
198 changes: 24 additions & 174 deletions docs/src/src/Zap.sol/contract.Zap.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Zap
[Git Source](https://github.com/moss-eth/zap/blob/70d3ea131ffe8af2f978b53f91daa0d8ac74d19a/src/Zap.sol)
[Git Source](https://github.com/moss-eth/zap/blob/59cf0756a77f382e301eda36c7e1793c595fd9b7/src/Zap.sol)

**Inherits:**
[Reentrancy](/src/utils/Reentrancy.sol/contract.Reentrancy.md), [Errors](/src/utils/Errors.sol/contract.Errors.md), [Flush](/src/utils/Flush.sol/contract.Flush.md)
Expand Down Expand Up @@ -90,27 +90,13 @@ address public immutable AAVE;
```


### FEE_TIER

```solidity
uint24 public constant FEE_TIER = 3000;
```


### ROUTER

```solidity
address public immutable ROUTER;
```


### QUOTER

```solidity
address public immutable QUOTER;
```


## Functions
### constructor

Expand All @@ -124,8 +110,7 @@ constructor(
address _referrer,
uint128 _susdcSpotId,
address _aave,
address _router,
address _quoter
address _router
);
```

Expand Down Expand Up @@ -469,7 +454,7 @@ function unwind(
bytes memory _path,
uint256 _zapMinAmountOut,
uint256 _unwrapMinAmountOut,
uint256 _swapMaxAmountIn,
uint256 _swapAmountIn,
address _receiver
)
external
Expand All @@ -484,10 +469,10 @@ function unwind(
|`_collateralId`|`uint128`|synthetix market id of collateral|
|`_collateralAmount`|`uint256`|amount of collateral to unwind|
|`_collateral`|`address`|address of collateral to unwind|
|`_path`|`bytes`|Uniswap swap path encoded in reverse order|
|`_path`|`bytes`|odos path from the sor/assemble api endpoint|
|`_zapMinAmountOut`|`uint256`|acceptable slippage for zapping|
|`_unwrapMinAmountOut`|`uint256`|acceptable slippage for unwrapping|
|`_swapMaxAmountIn`|`uint256`|acceptable slippage for swapping|
|`_swapAmountIn`|`uint256`|acceptable slippage for swapping|
|`_receiver`|`address`|address to receive unwound collateral|


Expand Down Expand Up @@ -683,200 +668,65 @@ function _withdraw(
internal;
```

### quoteSwapFor

query amount required to receive a specific amount of token

*this is the QuoterV1 interface*

*_path MUST be encoded backwards for `exactOutput`*

*quoting is NOT gas efficient and should NOT be called on chain*


```solidity
function quoteSwapFor(
bytes memory _path,
uint256 _amountOut
)
external
returns (
uint256 amountIn,
uint160[] memory sqrtPriceX96AfterList,
uint32[] memory initializedTicksCrossedList,
uint256 gasEstimate
);
```
**Parameters**

|Name|Type|Description|
|----|----|-----------|
|`_path`|`bytes`|Uniswap swap path encoded in reverse order|
|`_amountOut`|`uint256`|is the desired output amount|

**Returns**

|Name|Type|Description|
|----|----|-----------|
|`amountIn`|`uint256`|required as the input for the swap in order|
|`sqrtPriceX96AfterList`|`uint160[]`||
|`initializedTicksCrossedList`|`uint32[]`||
|`gasEstimate`|`uint256`||


### quoteSwapWith

query amount received for a specific amount of token to spend

*this is the QuoterV1 interface*

*_path MUST be encoded in order for `exactInput`*

*quoting is NOT gas efficient and should NOT be called on chain*


```solidity
function quoteSwapWith(
bytes memory _path,
uint256 _amountIn
)
external
returns (
uint256 amountOut,
uint160[] memory sqrtPriceX96AfterList,
uint32[] memory initializedTicksCrossedList,
uint256 gasEstimate
);
```
**Parameters**

|Name|Type|Description|
|----|----|-----------|
|`_path`|`bytes`|Uniswap swap path encoded in order|
|`_amountIn`|`uint256`|is the input amount to spendp|
### swapFrom

**Returns**
swap an amount of tokens for the optimal amount of USDC

|Name|Type|Description|
|----|----|-----------|
|`amountOut`|`uint256`|received as the output for the swap in order|
|`sqrtPriceX96AfterList`|`uint160[]`||
|`initializedTicksCrossedList`|`uint32[]`||
|`gasEstimate`|`uint256`||


### swapFor

swap a tolerable amount of tokens for a specific amount of USDC

*_path MUST be encoded backwards for `exactOutput`*
*_path USDC is not enforced as the output token during the swap, but
is the expected in the call to push*

*caller must grant token allowance to this contract*

*any excess token not spent will be returned to the caller*


```solidity
function swapFor(
function swapFrom(
address _from,
bytes memory _path,
uint256 _amount,
uint256 _maxAmountIn,
uint256 _amountIn,
address _receiver
)
external
returns (uint256 deducted);
returns (uint256 amountOut);
```
**Parameters**

|Name|Type|Description|
|----|----|-----------|
|`_from`|`address`|address of token to swap|
|`_path`|`bytes`|uniswap swap path encoded in reverse order|
|`_amount`|`uint256`|amount of USDC to receive in return|
|`_maxAmountIn`|`uint256`|max amount of token to spend|
|`_path`|`bytes`|odos path from the sor/assemble api endpoint|
|`_amountIn`|`uint256`|amount of token to spend|
|`_receiver`|`address`|address to receive USDC|

**Returns**

|Name|Type|Description|
|----|----|-----------|
|`deducted`|`uint256`|amount of incoming token; i.e., amount spent|
|`amountOut`|`uint256`|amount of tokens swapped for|


### _swapFor

*allowance is assumed*
### odosSwap

*following execution, this contract will hold the swapped USDC*


```solidity
function _swapFor(
address _from,
bytes memory _path,
uint256 _amount,
uint256 _maxAmountIn
function odosSwap(
address _tokenFrom,
uint256 _amountIn,
bytes memory _swapPath
)
internal
returns (uint256 deducted);
```

### swapWith

swap a specific amount of tokens for a tolerable amount of USDC

*_path MUST be encoded in order for `exactInput`*

*caller must grant token allowance to this contract*


```solidity
function swapWith(
address _from,
bytes memory _path,
uint256 _amount,
uint256 _amountOutMinimum,
address _receiver
)
external
returns (uint256 received);
returns (uint256 amountOut);
```
**Parameters**

|Name|Type|Description|
|----|----|-----------|
|`_from`|`address`|address of token to swap|
|`_path`|`bytes`|uniswap swap path encoded in order|
|`_amount`|`uint256`|of token to swap|
|`_amountOutMinimum`|`uint256`|tolerable amount of USDC to receive specified with 6 decimals|
|`_receiver`|`address`|address to receive USDC|

**Returns**

|Name|Type|Description|
|----|----|-----------|
|`received`|`uint256`|amount of USDC|


### _swapWith

*allowance is assumed*

*following execution, this contract will hold the swapped USDC*
|`_tokenFrom`|`address`|address of token being swapped|
|`_amountIn`|`uint256`|amount of token being swapped|
|`_swapPath`|`bytes`|bytes from odos assemble api containing the swap details|


```solidity
function _swapWith(
address _from,
bytes memory _path,
uint256 _amount,
uint256 _amountOutMinimum
)
internal
returns (uint256 received);
```

### _pull

*pull tokens from a sender*
Expand Down
2 changes: 1 addition & 1 deletion docs/src/src/interfaces/IAave.sol/interface.IPool.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# IPool
[Git Source](https://github.com/moss-eth/zap/blob/70d3ea131ffe8af2f978b53f91daa0d8ac74d19a/src/interfaces/IAave.sol)
[Git Source](https://github.com/moss-eth/zap/blob/59cf0756a77f382e301eda36c7e1793c595fd9b7/src/interfaces/IAave.sol)


## Functions
Expand Down
2 changes: 1 addition & 1 deletion docs/src/src/interfaces/IERC20.sol/interface.IERC20.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# IERC20
[Git Source](https://github.com/moss-eth/zap/blob/70d3ea131ffe8af2f978b53f91daa0d8ac74d19a/src/interfaces/IERC20.sol)
[Git Source](https://github.com/moss-eth/zap/blob/59cf0756a77f382e301eda36c7e1793c595fd9b7/src/interfaces/IERC20.sol)


## Functions
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# IPerpsMarket
[Git Source](https://github.com/moss-eth/zap/blob/70d3ea131ffe8af2f978b53f91daa0d8ac74d19a/src/interfaces/ISynthetix.sol)
[Git Source](https://github.com/moss-eth/zap/blob/59cf0756a77f382e301eda36c7e1793c595fd9b7/src/interfaces/ISynthetix.sol)


## Functions
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# ISpotMarket
[Git Source](https://github.com/moss-eth/zap/blob/70d3ea131ffe8af2f978b53f91daa0d8ac74d19a/src/interfaces/ISynthetix.sol)
[Git Source](https://github.com/moss-eth/zap/blob/59cf0756a77f382e301eda36c7e1793c595fd9b7/src/interfaces/ISynthetix.sol)


## Functions
Expand Down
2 changes: 1 addition & 1 deletion docs/src/src/interfaces/IUniswap.sol/interface.IQuoter.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# IQuoter
[Git Source](https://github.com/moss-eth/zap/blob/70d3ea131ffe8af2f978b53f91daa0d8ac74d19a/src/interfaces/IUniswap.sol)
[Git Source](https://github.com/moss-eth/zap/blob/59cf0756a77f382e301eda36c7e1793c595fd9b7/src/interfaces/IUniswap.sol)


## Functions
Expand Down
2 changes: 1 addition & 1 deletion docs/src/src/interfaces/IUniswap.sol/interface.IRouter.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# IRouter
[Git Source](https://github.com/moss-eth/zap/blob/70d3ea131ffe8af2f978b53f91daa0d8ac74d19a/src/interfaces/IUniswap.sol)
[Git Source](https://github.com/moss-eth/zap/blob/59cf0756a77f382e301eda36c7e1793c595fd9b7/src/interfaces/IUniswap.sol)


## Functions
Expand Down
Loading

0 comments on commit c8292c5

Please sign in to comment.