Skip to content

Commit

Permalink
Add governance token
Browse files Browse the repository at this point in the history
Also tweak the IThunderSwapReceiver
  • Loading branch information
mgnfy-view committed Apr 13, 2024
1 parent c592865 commit 2e895f8
Show file tree
Hide file tree
Showing 15 changed files with 230 additions and 23 deletions.
6 changes: 2 additions & 4 deletions docs/src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@

Thunder Swap is a decentralized exchange protocol that also supports flash swaps. A flash swap allows you to get a certain amount of a type of token within the pool as loan, and swap it for a certain amount of the other type of token in the pool, plus some minimal fee.

A thunder swap pool factory is deployed on-chain, and users can interact with it to deploy thunder swap pools for supported tokens (set by the deployer). Liquidity providers can supply pools with liquidity (using the `ThunderSwapPool::addLiquidity()` function) and earn fees (0.3%) on each swap. Each liquidity provider is minted LP (Liquidity Provider) tokens representing the portion of the pool they own. At any time, liquidity providers can exit the protocol by withdrawing their liquidity (using the `ThunderSwapPool::withdrawLiquidity()` function, which burns LP tokens) along with any accrued fees.
A thunder swap pool factory is deployed on-chain, and users can interact with it to deploy thunder swap pools for supported tokens (set by the deployer). Liquidity providers can supply pools with liquidity and earn a fees of 0.3% on each swap. Each liquidity provider is minted LP (Liquidity Provider) tokens representing the portion of the pool they own. At any time, liquidity providers can exit the protocol by burning these LP tokens, which allows them to withdraw their liquidity along with any accrued fees.

Both normal swaps and flash swaps take place using the `ThunderSwapPool::flashSwapExactInput()` and `ThunderSwapPool::flashSwapExactOutput()` functions. In a normal swap, the `receiver` address is the user's wallet address; however, in a flash swap, a user sets the `receiver` address as the contract address (which implements the `IThunderSwapReceiver` interface). The contract that receives the token loan has to ensure that enough tokens are approved to the `ThunderSwapPool` when the control returns to it and the loan is paid back (along with fees).
Both normal swaps and flash swaps take place using the `ThunderSwapPool::flashSwapExactInput()` and `ThunderSwapPool::flashSwapExactOutput()` functions. In a normal swap, the `receiver` address is the user's wallet address; however, in a flash swap, a user sets the `receiver` address as the contract's address (which is `IThunderSwapReceiver` interface compliant). The contract that receives the token loan has to ensure that enough tokens are approved to the `ThunderSwapPool` when the control returns to it and the loan is paid back (along with fees). With flash swaps, contracts can also activate hooks before and after a swap to fine tune their swapping strategy.


### Built With
Expand Down Expand Up @@ -149,8 +149,6 @@ Distributed under the MIT License. See `LICENSE.txt` for more information.

Sahil Gujrati - [@https://twitter.com/mgnfy_view](https://twitter.com/https://twitter.com/mgnfy_view) - sahilgujrati12@gmail.com

Project Link: [https://github.com/mgnfy-view/thunder-swap](https://github.com/mgnfy-view/thunder-swap)


<!-- ACKNOWLEDGMENTS -->
<!-- ## Acknowledgments
Expand Down
2 changes: 2 additions & 0 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
- [❱ core](src/core/README.md)
- [❱ interfaces](src/core/interfaces/README.md)
- [IThunderSwapPool](src/core/interfaces/IThunderSwapPool.sol/interface.IThunderSwapPool.md)
- [❱ lib](src/core/lib/README.md)
- [LiquiditySupplyAndSwapMath](src/core/lib/LiquiditySupplyAndSwapMath.sol/library.LiquiditySupplyAndSwapMath.md)
- [LiquidityProviderToken](src/core/LiquidityProviderToken.sol/contract.LiquidityProviderToken.md)
- [ThunderSwapPool](src/core/ThunderSwapPool.sol/contract.ThunderSwapPool.md)
- [ThunderSwapPoolFactory](src/core/ThunderSwapPoolFactory.sol/contract.ThunderSwapPoolFactory.md)
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# IThunderSwapHooks
[Git Source](https://github.com/Sahil-Gujrati/thunder-swap/blob/65d96eb516be89fd9526025068582cb68137dd6f/src/ThunderSwapReceiver/interfaces/IThunderSwapHooks.sol)
[Git Source](https://github.com/Sahil-Gujrati/thunder-swap/blob/c5928651e4c994aae9565d571bef4170237837f3/src/ThunderSwapReceiver/interfaces/IThunderSwapHooks.sol)


## Functions
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# IThunderSwapReceiver
[Git Source](https://github.com/Sahil-Gujrati/thunder-swap/blob/65d96eb516be89fd9526025068582cb68137dd6f/src/ThunderSwapReceiver/interfaces/IThunderSwapReceiver.sol)
[Git Source](https://github.com/Sahil-Gujrati/thunder-swap/blob/c5928651e4c994aae9565d571bef4170237837f3/src/ThunderSwapReceiver/interfaces/IThunderSwapReceiver.sol)

**Inherits:**
[IThunderSwapHooks](/src/ThunderSwapReceiver/interfaces/IThunderSwapHooks.sol/interface.IThunderSwapHooks.md)
Expand All @@ -18,7 +18,8 @@ function onThunderSwapReceived(
IERC20 _outputToken,
uint256 _outputAmount
)
external;
external
returns (string memory);
```
**Parameters**

Expand All @@ -29,4 +30,10 @@ function onThunderSwapReceived(
|`_outputToken`|`IERC20`|The output token|
|`_outputAmount`|`uint256`|The output token amount|

**Returns**

|Name|Type|Description|
|----|----|-----------|
|`<none>`|`string`|Return the string "Thunder Swap" for security concerns|


Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
# LiquidityProviderToken
[Git Source](https://github.com/Sahil-Gujrati/thunder-swap/blob/65d96eb516be89fd9526025068582cb68137dd6f/src/core/LiquidityProviderToken.sol)
[Git Source](https://github.com/Sahil-Gujrati/thunder-swap/blob/c5928651e4c994aae9565d571bef4170237837f3/src/core/LiquidityProviderToken.sol)

**Inherits:**
ERC20, Ownable

**Author:**
mgnfy-view

This is the ERC20 token that each `ThunderSwaPool` uses to keep track of the liquidity
supplied by LPs


## Functions
### constructor
Expand Down
1 change: 1 addition & 0 deletions docs/src/src/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# Contents
- [interfaces](/src/core/interfaces)
- [lib](/src/core/lib)
- [LiquidityProviderToken](LiquidityProviderToken.sol/contract.LiquidityProviderToken.md)
- [ThunderSwapPool](ThunderSwapPool.sol/contract.ThunderSwapPool.md)
- [ThunderSwapPoolFactory](ThunderSwapPoolFactory.sol/contract.ThunderSwapPoolFactory.md)
23 changes: 15 additions & 8 deletions docs/src/src/core/ThunderSwapPool.sol/contract.ThunderSwapPool.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# ThunderSwapPool
[Git Source](https://github.com/Sahil-Gujrati/thunder-swap/blob/65d96eb516be89fd9526025068582cb68137dd6f/src/core/ThunderSwapPool.sol)
[Git Source](https://github.com/Sahil-Gujrati/thunder-swap/blob/c5928651e4c994aae9565d571bef4170237837f3/src/core/ThunderSwapPool.sol)

**Inherits:**
[IThunderSwapPool](/src/core/interfaces/IThunderSwapPool.sol/interface.IThunderSwapPool.md), ReentrancyGuard
Expand Down Expand Up @@ -110,7 +110,8 @@ function addLiquidity(

### withdrawLiquidity

Allows liquidity providers to exit the protocol by withdrawing their deposited liquidity
Allows liquidity providers to exit the protocol by withdrawing their deposited
liquidity


```solidity
Expand Down Expand Up @@ -492,8 +493,8 @@ function _addLiquidity(

### _withdrawLiquidity

Sends pool token 1 and pool token 2 amount to the LP. Helper for the `withdrawLiquidity`
function
Sends pool token 1 and pool token 2 amount to the LP. Helper for the
`withdrawLiquidity` function


```solidity
Expand All @@ -517,10 +518,10 @@ function _withdrawLiquidity(

Flash swaps input token amount for the output token amount. The output token is first
sent to the receiver, and the `onThunderSwapReceived()` function is called if `_callContract`
is set to true. Then, in the same transaction, the receiver contract approves the amount of input
token to send, and this function transfers the amount to the protocol. There can be no intermediate
contract, and wallets can directly swap tokens as well by setting `_callContract` to false, and
`receiver` to the wallet address
is set to true. Then, in the same transaction, the receiver contract approves the amount of
input token to send, and this function transfers the amount to the protocol. There can be no
intermediate contract, and wallets can directly swap tokens as well by setting
`_callContract` to false, and `receiver` to the wallet address


```solidity
Expand Down Expand Up @@ -661,3 +662,9 @@ error PoolTokenToSendMoreThanMaximumPoolTokenToSend(
);
```

### IncompatibleContract

```solidity
error IncompatibleContract();
```

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# ThunderSwapPoolFactory
[Git Source](https://github.com/Sahil-Gujrati/thunder-swap/blob/65d96eb516be89fd9526025068582cb68137dd6f/src/core/ThunderSwapPoolFactory.sol)
[Git Source](https://github.com/Sahil-Gujrati/thunder-swap/blob/c5928651e4c994aae9565d571bef4170237837f3/src/core/ThunderSwapPoolFactory.sol)

**Inherits:**
Ownable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,42 @@
# IThunderSwapPool
[Git Source](https://github.com/Sahil-Gujrati/thunder-swap/blob/65d96eb516be89fd9526025068582cb68137dd6f/src/core/interfaces/IThunderSwapPool.sol)
[Git Source](https://github.com/Sahil-Gujrati/thunder-swap/blob/c5928651e4c994aae9565d571bef4170237837f3/src/core/interfaces/IThunderSwapPool.sol)


## Functions
### addLiquidity

Allows users to become liquidity providers by supplying the protocol with liquidity

*Pool token 2 to supply is calculated based on pool token 1 amount. However, at inception
the first LP can decide on the ratio of his/her deposit*


```solidity
function addLiquidity(
uint256 _poolToken1Amount,
uint256 _poolToken2Amount,
uint256 _maximumPoolToken2ToDeposit,
uint256 _minimumLPTokensToMint,
uint256 _minimumLiquidityProviderTokensToMint,
uint256 _deadline
)
external;
```
**Parameters**

|Name|Type|Description|
|----|----|-----------|
|`_poolToken1Amount`|`uint256`|The amount of pool token 1 to add as liquidity|
|`_poolToken2Amount`|`uint256`|The amount of pool token 2 to add as liquidity|
|`_maximumPoolToken2ToDeposit`|`uint256`|(slippage protection) The maximum amount of pool token 2 to deposit based on pool token 1 amount|
|`_minimumLiquidityProviderTokensToMint`|`uint256`|(slippage protection) The minimum share of the pool the liquidity provider is expecting to own|
|`_deadline`|`uint256`|Deadline before which the liquidity should be added|


### withdrawLiquidity

Allows liquidity providers to exit the protocol by withdrawing their deposited
liquidity


```solidity
function withdrawLiquidity(
Expand All @@ -29,9 +47,20 @@ function withdrawLiquidity(
)
external;
```
**Parameters**

|Name|Type|Description|
|----|----|-----------|
|`_liquidityProviderTokensToBurn`|`uint256`|The amount of LP tokens the LP wants to burn to claim his/her liquidity|
|`_minimumPoolToken1ToWithdraw`|`uint256`|(slippage protection) The minimum pool token 1 amount the LP is expecting to withdraw|
|`_minimumPoolToken2ToWithdraw`|`uint256`|(slippage protection) The minimum pool token 2 amount the LP is expecting to withdraw|
|`_deadline`|`uint256`|Deadline before which the liquidity should be withdrawn|


### flashSwapExactInput

Flash swaps exact amount of input token for output token


```solidity
function flashSwapExactInput(
Expand All @@ -46,9 +75,24 @@ function flashSwapExactInput(
)
external;
```
**Parameters**

|Name|Type|Description|
|----|----|-----------|
|`_inputToken`|`IERC20`|The input token (supported by the pool)|
|`_inputAmount`|`uint256`|The amount of input token to send|
|`_minimumOutputTokenToReceive`|`uint256`|(slippage protection) The minimum amount of output token to receive|
|`_receiver`|`address`|Receiver of the output token amount (contract, or a wallet)|
|`_callContract`|`bool`|If true, call the `onThunderSwapReceived()` function on the receiver contract|
|`_callBeforeHook`|`bool`|if true, calls the `beforeThunderSwapReceived` hook on the receiver contract|
|`_callAfterHook`|`bool`|if true, calls the `afterThunderSwapReceived` hook on the receiver contract|
|`_deadline`|`uint256`|Deadline before which the flash swap should occur|


### flashSwapExactOutput

Flash swaps a certain amount of input token for an exact amount of output token


```solidity
function flashSwapExactOutput(
Expand All @@ -63,4 +107,17 @@ function flashSwapExactOutput(
)
external;
```
**Parameters**

|Name|Type|Description|
|----|----|-----------|
|`_outputToken`|`IERC20`|The output token (supported by the pool)|
|`_outputAmount`|`uint256`|The amount of output token to receive|
|`_maximumInputTokensToSend`|`uint256`|(slippage protection) The maximum amount of input token to send|
|`_receiver`|`address`|Receiver of the output token amount (contract, or a wallet)|
|`_callContract`|`bool`|If true, call the `onThunderSwapReceived()` function on the receiver contract|
|`_callBeforeHook`|`bool`|if true, calls the `beforeThunderSwapReceived` hook on the receiver contract|
|`_callAfterHook`|`bool`|if true, calls the `afterThunderSwapReceived` hook on the receiver contract|
|`_deadline`|`uint256`|Deadline before which the flash swap should occur|


Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# LiquiditySupplyAndSwapMath
[Git Source](https://github.com/Sahil-Gujrati/thunder-swap/blob/c5928651e4c994aae9565d571bef4170237837f3/src/core/lib/LiquiditySupplyAndSwapMath.sol)


## Functions
### getPoolToken2LiquidityToAddBasedOnPoolToken1Amount


```solidity
function getPoolToken2LiquidityToAddBasedOnPoolToken1Amount(
uint256 _poolToken1Amount,
uint256 _poolToken1Reserves,
uint256 _poolToken2Reserves
)
internal
pure
returns (uint256);
```

### getPoolToken1LiquidityToAddBasedOnPoolToken2Amount


```solidity
function getPoolToken1LiquidityToAddBasedOnPoolToken2Amount(
uint256 _poolToken2Amount,
uint256 _poolToken1Reserves,
uint256 _poolToken2Reserves
)
internal
pure
returns (uint256);
```

### getLiquidityProviderTokensToMint


```solidity
function getLiquidityProviderTokensToMint(
uint256 _poolToken1AmountToDeposit,
uint256 _totalLiquidityProviderTokenSupply,
uint256 _poolToken1reserves
)
public
pure
returns (uint256);
```

### getInputBasedOnOuput


```solidity
function getInputBasedOnOuput(
uint256 _outputAmount,
uint256 _inputReserves,
uint256 _outputReserves,
uint256 _feeNumerator,
uint256 _feeDenominator
)
public
pure
returns (uint256);
```

### getOutputBasedOnInput


```solidity
function getOutputBasedOnInput(
uint256 _inputAmount,
uint256 _inputReserves,
uint256 _outputReserves,
uint256 _feeNumerator,
uint256 _feeDenominator
)
public
pure
returns (uint256);
```

4 changes: 4 additions & 0 deletions docs/src/src/core/lib/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@


# Contents
- [LiquiditySupplyAndSwapMath](LiquiditySupplyAndSwapMath.sol/library.LiquiditySupplyAndSwapMath.md)
4 changes: 3 additions & 1 deletion src/ThunderSwapReceiver/interfaces/IThunderSwapReceiver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ interface IThunderSwapReceiver is IThunderSwapHooks {
* @param _inputAmount The input token amount
* @param _outputToken The output token
* @param _outputAmount The output token amount
* @return Return the string "Thunder Swap" for security concerns
*/
function onThunderSwapReceived(
IERC20 _inputToken,
uint256 _inputAmount,
IERC20 _outputToken,
uint256 _outputAmount
)
external;
external
returns (string memory);
}
10 changes: 7 additions & 3 deletions src/core/ThunderSwapPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ contract ThunderSwapPool is IThunderSwapPool, ReentrancyGuard {
error PoolTokenToSendMoreThanMaximumPoolTokenToSend(
IERC20 inputToken, uint256 inputAmount, uint256 maximumInputAmount
);
error IncompatibleContract();

modifier notZero(uint256 _inputValue) {
if (_inputValue == 0) revert InputValueZeroNotAllowed();
Expand Down Expand Up @@ -516,18 +517,21 @@ contract ThunderSwapPool is IThunderSwapPool, ReentrancyGuard {
{
_outputToken.safeTransfer(_receiver, _outputAmount);

if (_callBeforeHook) {
if (_callContract && _callBeforeHook) {
IThunderSwapReceiver(_receiver).beforeThunderSwapReceived(
_inputToken, _inputAmount, _outputToken, _outputAmount
);
}
if (_callContract) {
IThunderSwapReceiver(_receiver).onThunderSwapReceived(
(string memory check) = IThunderSwapReceiver(_receiver).onThunderSwapReceived(
_inputToken, _inputAmount, _outputToken, _outputAmount
);
if (keccak256(abi.encodePacked(check)) != keccak256(abi.encodePacked("Thunder Swap"))) {
revert IncompatibleContract();
}
}
_inputToken.safeTransferFrom(_receiver, address(this), _inputAmount);
if (_callAfterHook) {
if (_callContract && _callAfterHook) {
IThunderSwapReceiver(_receiver).afterThunderSwapReceived(
_inputToken, _inputAmount, _outputToken, _outputAmount
);
Expand Down
Loading

0 comments on commit 2e895f8

Please sign in to comment.