Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
dhruvinparikh committed Dec 5, 2024
1 parent 49e11d7 commit 5cb2997
Show file tree
Hide file tree
Showing 7 changed files with 329 additions and 112 deletions.
85 changes: 30 additions & 55 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,41 @@
## Foundry
# Points hook

**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.**
* Simple on chain reward program
* launching a memecoin - "TOKEN"

Foundry consists of:
* setup a pool with ETH/TOKEN
* issue points for every time somebody buys TOKEN with ETH
* issue points for everytime somebody adds liquidity to the pool

- **Forge**: Ethereum testing framework (like Truffle, Hardhat and DappTools).
- **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data.
- **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network.
- **Chisel**: Fast, utilitarian, and verbose solidity REPL.
**THIS IS NOT PRODUCTION READY. If we have time we'll discuss about limitations and how to fix them**

## Documentation
## How many poins to give out?
* 20% of value in ETH. if alice sells 1 ETH to buy TOKEN, it will receive 0.2 points.
* For adding liquidity , we'll keep 1:1 for ETH added

https://book.getfoundry.sh/
## Mechanism design

## Usage
1. issue points evertime somebody buy TOKEN for ETH
* afterSwap : the amount of ETH can be only known after swap has happened
* issue points proportional to amount of ETH being sent from user for swap

### Build
2. issue points everytime somebody add liquidity
* afterAddLiquidity

```shell
$ forge build
```
## BalanceDelta
* Represents changes in the balance of token0 and token1
* BalanceDelta = (amount0Delta amount1Delta)
* Alice sells 1 ETH for TOKEN in our pool after swap is done
* BalanceDelta = (-1 ETH, +500 TOKEN)

### Test
----------------------------------------------------

```shell
$ forge test
```
* whenever there is a balance change , all number in uniswap by convention are represented from user perspective
* amount0Delta = -1 ETH => user needs to send 1 ETH to uniswap (user owes 1 ETH)
* amount1Delta = 500 token => User is owed 500 tokens from uniswap (uniswap needs to send 500 tokens to user)

### Format

```shell
$ forge fmt
```

### Gas Snapshots

```shell
$ forge snapshot
```

### Anvil

```shell
$ anvil
```

### Deploy

```shell
$ forge script script/Counter.s.sol:CounterScript --rpc-url <your_rpc_url> --private-key <your_private_key>
```

### Cast

```shell
$ cast <subcommand>
```

### Help

```shell
$ forge --help
$ anvil --help
$ cast --help
```
## zeroForOne
* exactInput(...) : zero for one
* exactInput(...) : one for zero
* exactOutput(...) : zero for one
* exactOutput(...) : one for zero
14 changes: 14 additions & 0 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@ensdomains/=lib/v4-periphery/lib/v4-core/node_modules/@ensdomains/
@openzeppelin/=lib/v4-periphery/lib/v4-core/lib/openzeppelin-contracts/
@openzeppelin/contracts/=lib/v4-periphery/lib/v4-core/lib/openzeppelin-contracts/contracts/
@uniswap/v4-core/=lib/v4-periphery/lib/v4-core/
ds-test/=lib/v4-periphery/lib/v4-core/lib/forge-std/lib/ds-test/src/
erc4626-tests/=lib/v4-periphery/lib/v4-core/lib/openzeppelin-contracts/lib/erc4626-tests/
forge-gas-snapshot/=lib/v4-periphery/lib/forge-gas-snapshot/src/
forge-std/=lib/forge-std/src/
hardhat/=lib/v4-periphery/lib/v4-core/node_modules/hardhat/
openzeppelin-contracts/=lib/v4-periphery/lib/v4-core/lib/openzeppelin-contracts/
permit2/=lib/v4-periphery/lib/permit2/
solmate/=lib/v4-periphery/lib/v4-core/lib/solmate/
v4-core/=lib/v4-periphery/lib/v4-core/src/
v4-periphery/=lib/v4-periphery/
19 changes: 0 additions & 19 deletions script/Counter.s.sol

This file was deleted.

14 changes: 0 additions & 14 deletions src/Counter.sol

This file was deleted.

109 changes: 109 additions & 0 deletions src/LoyaltyPointsHook.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import {BaseHook} from "v4-periphery/src/base/hooks/BaseHook.sol";
import {ERC1155} from "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import {Hooks} from "v4-core/libraries/Hooks.sol";

import {StateLibrary} from "v4-core/libraries/StateLibrary.sol";
import {TickMath} from "v4-core/libraries/TickMath.sol";

import {PoolId} from "v4-core/types/PoolId.sol";
import {IPoolManager} from "v4-core/interfaces/IPoolManager.sol";

import {PoolKey} from "v4-core/types/PoolKey.sol";

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

import {BalanceDelta} from "v4-core/types/BalanceDelta.sol";

import {CurrencyLibrary, Currency} from "v4-core/types/Currency.sol";

import {FixedPointMathLib} from "solmate/src/utils/FixedPointMathLib.sol";

contract LoyaltyPointsHook is BaseHook, ERC20 {
using CurrencyLibrary for Currency;

constructor(
IPoolManager _manager,
string memory _name,
string memory _symbol
) BaseHook(_manager) ERC20(_name, _symbol) {}

function getHookPermissions()
public
pure
override
returns (Hooks.Permissions memory)
{
return
Hooks.Permissions({
beforeInitialize: false,
afterInitialize: false,
beforeAddLiquidity: false,
afterAddLiquidity: true,
beforeRemoveLiquidity: false,
afterRemoveLiquidity: false,
beforeSwap: false,
afterSwap: true,
beforeDonate: false,
afterDonate: false,
beforeSwapReturnDelta: false,
afterSwapReturnDelta: false,
afterAddLiquidityReturnDelta: false,
afterRemoveLiquidityReturnDelta: false
});
}

function afterSwap(
address,
PoolKey calldata key,
IPoolManager.SwapParams calldata,
BalanceDelta delta,
bytes calldata hookData
) external override returns (bytes4, int128) {
if (!key.currency0.isAddressZero()) {
return (this.afterSwap.selector, 0);
}

uint256 ethSpent = uint256(int256(-delta.amount0()));
uint256 pointsForSwap = ethSpent / 5;

_assigningLoyaltyPoints(hookData, pointsForSwap);

return (this.afterSwap.selector, 0);
}

function afterAddLiquidity(
address,
PoolKey calldata key,
IPoolManager.ModifyLiquidityParams calldata,
BalanceDelta delta,
BalanceDelta,
bytes calldata hookData
) external override returns (bytes4, BalanceDelta) {
if (!key.currency0.isAddressZero()) {
return (this.afterSwap.selector, delta);
}

uint256 pointsForAddingLiquidity = uint256(int256(-delta.amount0()));

_assigningLoyaltyPoints(hookData, pointsForAddingLiquidity);

return (this.afterAddLiquidity.selector, delta);
}

function _assigningLoyaltyPoints(
bytes memory hookdata,
uint256 points
) internal {
if (hookdata.length == 0) return;

address user = abi.decode(hookdata, (address));

if (user == address(0)) return;

_mint(user, points);
}
}
24 changes: 0 additions & 24 deletions test/Counter.t.sol

This file was deleted.

Loading

0 comments on commit 5cb2997

Please sign in to comment.