Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Add lint #28

Merged
merged 1 commit into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ jobs:
- name: Install Dependencies
run: yarn install

- name: Run lint
run: yarn lint:check

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
Expand All @@ -32,6 +35,6 @@ jobs:

- name: Run tests
run: forge test -vvv --evm-version shanghai --fork-url ${{ secrets.SEPOLIA_FORK_URL }}

- name: Upload Selectors
run: forge selectors upload --all
8 changes: 8 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
build
cache
out
lib
node_modules
artifacts
etherscan.json
.vscode
14 changes: 14 additions & 0 deletions .prettierrc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
plugins: ["prettier-plugin-solidity"]
arrowParens: "avoid"
bracketSpacing: true
endOfLine: "auto"
printWidth: 100
singleQuote: false
tabWidth: 2
trailingComma: "all"

overrides:
- files: ["*.sol", "*.t.sol"]
options:
tabWidth: 4
parser: "solidity-parse"
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
Click "Use this template" on [GitHub](https://github.com/foundry-rs/forge-template) to create a new repository with this repo as the initial state.

Or, if your repo already exists, run:

```sh
forge init
forge build
Expand All @@ -25,12 +26,12 @@ pragma solidity 0.8.10;
import "forge-std/Test.sol";

contract ContractTest is Test {
function testExample() public {
vm.roll(100);
console.log(1);
emit log("hi");
assertTrue(true);
}
function testExample() public {
vm.roll(100);
console.log(1);
emit log("hi");
assertTrue(true);
}
}
```

Expand Down
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"devDependencies": {
"prettier": "^3.2.5",
"prettier-plugin-solidity": "^1.3.1"
},
"scripts": {
"lint:fix": "prettier --write .",
"lint:check": "prettier --check ."
}
}
28 changes: 7 additions & 21 deletions src/ERC20Creator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity ^0.8.0;
import "../lib/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
import "../lib/v2-core/contracts/interfaces/IUniswapV2Factory.sol";
import "party-protocol/contracts/distribution/ITokenDistributor.sol";
import {GovernableERC20, ERC20} from "./GovernableERC20.sol";
import { GovernableERC20, ERC20 } from "./GovernableERC20.sol";

contract ERC20Creator {
event ERC20Created(
Expand All @@ -17,14 +17,8 @@ contract ERC20Creator {
TokenConfiguration config
);

event FeeRecipientUpdated(
address indexed oldFeeRecipient,
address indexed newFeeRecipient
);
event FeeBasisPointsUpdated(
uint16 oldFeeBasisPoints,
uint16 newFeeBasisPoints
);
event FeeRecipientUpdated(address indexed oldFeeRecipient, address indexed newFeeRecipient);
event FeeBasisPointsUpdated(uint16 oldFeeBasisPoints, uint16 newFeeBasisPoints);

error InvalidFeeBasisPoints();
error InvalidTokenDistribution();
Expand Down Expand Up @@ -80,19 +74,11 @@ contract ERC20Creator {
}

// Create token
token = new GovernableERC20(
name,
symbol,
config.totalSupply,
address(this)
);
token = new GovernableERC20(name, symbol, config.totalSupply, address(this));

if (config.numTokensForDistribution > 0) {
// Create distribution
token.transfer(
address(TOKEN_DISTRIBUTOR),
config.numTokensForDistribution
);
token.transfer(address(TOKEN_DISTRIBUTOR), config.numTokensForDistribution);
TOKEN_DISTRIBUTOR.createErc20Distribution(
IERC20(address(token)),
Party(payable(partyAddress)),
Expand All @@ -108,7 +94,7 @@ contract ERC20Creator {
// Create locked LP pair
uint256 numETHForLP = ethValue - feeAmount;
token.approve(address(UNISWAP_V2_ROUTER), config.numTokensForLP);
UNISWAP_V2_ROUTER.addLiquidityETH{value: numETHForLP}(
UNISWAP_V2_ROUTER.addLiquidityETH{ value: numETHForLP }(
address(token),
config.numTokensForLP,
config.numTokensForLP,
Expand All @@ -121,7 +107,7 @@ contract ERC20Creator {
token.transfer(recipientAddress, config.numTokensForRecipient);

// Send fee
feeRecipient.call{value: feeAmount, gas: 100_000}("");
feeRecipient.call{ value: feeAmount, gas: 100_000 }("");

emit ERC20Created(
address(token),
Expand Down
77 changes: 24 additions & 53 deletions src/ERC20CreatorV3.sol
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {Math} from "openzeppelin-contracts/contracts/utils/math/Math.sol";
import {INonfungiblePositionManager} from "v3-periphery/interfaces/INonfungiblePositionManager.sol";
import {IMulticall} from "v3-periphery/interfaces/IMulticall.sol";
import {IUniswapV3Factory} from "v3-core/contracts/interfaces/IUniswapV3Factory.sol";
import {IUniswapV3Pool} from "v3-core/contracts/interfaces/IUniswapV3Pool.sol";
import {IERC721Receiver} from "openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol";
import {ITokenDistributor, IERC20, Party} from "party-protocol/contracts/distribution/ITokenDistributor.sol";
import {GovernableERC20} from "./GovernableERC20.sol";
import {FeeRecipient} from "./FeeCollector.sol";
import { Math } from "openzeppelin-contracts/contracts/utils/math/Math.sol";
import { INonfungiblePositionManager } from "v3-periphery/interfaces/INonfungiblePositionManager.sol";
import { IMulticall } from "v3-periphery/interfaces/IMulticall.sol";
import { IUniswapV3Factory } from "v3-core/contracts/interfaces/IUniswapV3Factory.sol";
import { IUniswapV3Pool } from "v3-core/contracts/interfaces/IUniswapV3Pool.sol";
import { IERC721Receiver } from "openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol";
import { ITokenDistributor, IERC20, Party } from "party-protocol/contracts/distribution/ITokenDistributor.sol";
import { GovernableERC20 } from "./GovernableERC20.sol";
import { FeeRecipient } from "./FeeCollector.sol";

contract ERC20CreatorV3 is IERC721Receiver {
struct TokenDistributionConfiguration {
Expand All @@ -29,15 +29,9 @@ contract ERC20CreatorV3 is IERC721Receiver {
TokenDistributionConfiguration config
);

event FeeRecipientUpdated(
address indexed oldFeeRecipient,
address indexed newFeeRecipient
);
event FeeRecipientUpdated(address indexed oldFeeRecipient, address indexed newFeeRecipient);

event FeeBasisPointsUpdated(
uint16 oldFeeBasisPoints,
uint16 newFeeBasisPoints
);
event FeeBasisPointsUpdated(uint16 oldFeeBasisPoints, uint16 newFeeBasisPoints);

error InvalidTokenDistribution();
error OnlyFeeRecipient();
Expand Down Expand Up @@ -84,8 +78,7 @@ contract ERC20CreatorV3 is IERC721Receiver {
uint16 feeBasisPoints_,
uint16 poolFee
) {
if (poolFee != 500 && poolFee != 3000 && poolFee != 10_000)
revert InvalidPoolFee();
if (poolFee != 500 && poolFee != 3000 && poolFee != 10_000) revert InvalidPoolFee();
if (feeBasisPoints_ > 5e3) revert InvalidFeeBasisPoints();

TOKEN_DISTRIBUTOR = tokenDistributor;
Expand All @@ -99,9 +92,7 @@ contract ERC20CreatorV3 is IERC721Receiver {

int24 tickSpacing = UNISWAP_V3_FACTORY.feeAmountTickSpacing(POOL_FEE);
MAX_TICK = (887272 /* TickMath.MAX_TICK */ / tickSpacing) * tickSpacing;
MIN_TICK =
(-887272 /* TickMath.MIN_TICK */ / tickSpacing) *
tickSpacing;
MIN_TICK = (-887272 /* TickMath.MIN_TICK */ / tickSpacing) * tickSpacing;
}

/// @notice Creates a new ERC20 token, LPs it in a locked full range Uniswap V3 position, and distributes some of the new token to party members.
Expand Down Expand Up @@ -137,19 +128,14 @@ contract ERC20CreatorV3 is IERC721Receiver {
IERC20 token = IERC20(
address(
new GovernableERC20{
salt: keccak256(
abi.encode(blockhash(block.number - 1), msg.sender)
)
salt: keccak256(abi.encode(blockhash(block.number - 1), msg.sender))
}(name, symbol, config.totalSupply, address(this))
)
);

if (config.numTokensForDistribution > 0) {
// Create distribution
token.transfer(
address(TOKEN_DISTRIBUTOR),
config.numTokensForDistribution
);
token.transfer(address(TOKEN_DISTRIBUTOR), config.numTokensForDistribution);
TOKEN_DISTRIBUTOR.createErc20Distribution(
token,
Party(payable(party)),
Expand All @@ -173,22 +159,13 @@ contract ERC20CreatorV3 is IERC721Receiver {
: (config.numTokensForLP, msg.value - feeAmount);

// Create and initialize pool. Reverts if pool already created.
address pool = UNISWAP_V3_FACTORY.createPool(
address(token),
WETH,
POOL_FEE
);
address pool = UNISWAP_V3_FACTORY.createPool(address(token), WETH, POOL_FEE);

// Initialize pool for the derived starting price
uint160 sqrtPriceX96 = uint160(
(Math.sqrt((amount1 * 1e18) / amount0) * _X96) / 1e9
);
uint160 sqrtPriceX96 = uint160((Math.sqrt((amount1 * 1e18) / amount0) * _X96) / 1e9);
IUniswapV3Pool(pool).initialize(sqrtPriceX96);

token.approve(
address(UNISWAP_V3_POSITION_MANAGER),
config.numTokensForLP
);
token.approve(address(UNISWAP_V3_POSITION_MANAGER), config.numTokensForLP);

// Use multicall to sweep back excess ETH
bytes[] memory calls = new bytes[](2);
Expand All @@ -210,12 +187,9 @@ contract ERC20CreatorV3 is IERC721Receiver {
})
)
);
calls[1] = abi.encodePacked(
UNISWAP_V3_POSITION_MANAGER.refundETH.selector
);
bytes memory mintReturnData = IMulticall(
address(UNISWAP_V3_POSITION_MANAGER)
).multicall{value: msg.value - feeAmount}(calls)[0];
calls[1] = abi.encodePacked(UNISWAP_V3_POSITION_MANAGER.refundETH.selector);
bytes memory mintReturnData = IMulticall(address(UNISWAP_V3_POSITION_MANAGER))
.multicall{ value: msg.value - feeAmount }(calls)[0];

lpTokenId = abi.decode(mintReturnData, (uint256));
}
Expand All @@ -237,19 +211,16 @@ contract ERC20CreatorV3 is IERC721Receiver {

// Transfer fee
if (feeAmount > 0) {
feeRecipient.call{value: feeAmount, gas: 100_000}("");
feeRecipient.call{ value: feeAmount, gas: 100_000 }("");
}

// Transfer remaining ETH to the party
if (address(this).balance > 0) {
payable(party).call{value: address(this).balance, gas: 100_000}("");
payable(party).call{ value: address(this).balance, gas: 100_000 }("");
}

FeeRecipient[] memory recipients = new FeeRecipient[](1);
recipients[0] = FeeRecipient({
recipient: payable(lpFeeRecipient),
percentageBps: 10_000
});
recipients[0] = FeeRecipient({ recipient: payable(lpFeeRecipient), percentageBps: 10_000 });

// Transfer LP to fee collector contract
UNISWAP_V3_POSITION_MANAGER.safeTransferFrom(
Expand Down
Loading
Loading