Skip to content

Commit

Permalink
Merge pull request #18 from DODOEX/feat/admin
Browse files Browse the repository at this point in the history
Feat/admin
  • Loading branch information
Attens1423 authored Jun 12, 2024
2 parents 17baaae + 204a959 commit a634be3
Show file tree
Hide file tree
Showing 17 changed files with 76 additions and 23 deletions.
Binary file added .DS_Store
Binary file not shown.
4 changes: 2 additions & 2 deletions .github/workflows/coverage-foundry.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ jobs:

steps:
- name: Check out
uses: actions/checkout@v2
- uses: actions/setup-node@v2
uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: yarn

- name: Install Foundry
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/coverage-hardhat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:

steps:
- name: Check out
uses: actions/checkout@v2
- uses: actions/setup-node@v2
uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: yarn
- run: yarn coverage
4 changes: 2 additions & 2 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:

steps:
- name: Check out
uses: actions/checkout@v2
- uses: actions/setup-node@v2
uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: yarn
- run: yarn integration
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:

steps:
- name: Check out
uses: actions/checkout@v2
- uses: actions/setup-node@v2
uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: yarn add solhint
- run: yarn lint
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
submodules: recursive

- uses: actions/setup-node@v2
- uses: actions/setup-node@v4
- run: yarn

- uses: onbjerg/foundry-toolchain@v1
with:
version: nightly

- run: forge test
- run: forge test --fork-url https://eth.llamarpc.com
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ coverage.json
lcov.info

.vscode
.DS_Store
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ Main Contract: ./contracts/GasSavingPool/impl/

GSP is a advanced version of DODO V2 [DSP](https://docs.dodoex.io/en/product/dodo-v2-pools/dodo-stable-pool). The whole contracts of GSP uses solidity 0.8.16 version. It provides user with two methods to swap, including sellBase and sellQuote. Same as DSP, GSP supports flashloan. Compared with of DSP and UniV3, GSP can perform swap at a cost of much lower gas fee.

GSP add two features:
- Admin can adjust oracle price and price limit. There are two functions:
- adjustPrice(): Admin adjust oracle price
- adjustPriceLimit(): Set price limit which limit the price change amplitude. The relative ratio of the newly set price to the old price cannot exceed this value, with the unit being 1e6. The default value is 1e3, meaning the relative price change amplitude cannot exceed 1e3/1e6 = 0.1%.
- Maintainer need to claim mtFee in pool

Inheritaged a template using Foundry && HardHat architecture. We use foundry test.

## Diff Report from DSP
Expand Down
3 changes: 3 additions & 0 deletions contracts/GasSavingPool/impl/GSP.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ contract GSP is GSPTrader, GSPFunding {
/**
* @notice Function will be called in factory, init risk should not be included.
* @param maintainer The dodo's address, who can claim mtFee and own this pool
* @param admin oracle owner address, who can set price.
* @param baseTokenAddress The base token address
* @param quoteTokenAddress The quote token address
* @param lpFeeRate The rate of lp fee, with 18 decimal
Expand All @@ -33,6 +34,7 @@ contract GSP is GSPTrader, GSPFunding {
*/
function init(
address maintainer,
address admin,
address baseTokenAddress,
address quoteTokenAddress,
uint256 lpFeeRate,
Expand Down Expand Up @@ -64,6 +66,7 @@ contract GSP is GSPTrader, GSPFunding {
_MT_FEE_RATE_ = mtFeeRate;
// _MAINTAINER_ is set when initialization, the address receives the fee
_MAINTAINER_ = maintainer;
_ADMIN_ = admin;
// _IS_OPEN_TWAP_ is always false
_IS_OPEN_TWAP_ = false;

Expand Down
2 changes: 2 additions & 0 deletions contracts/GasSavingPool/impl/GSPStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ contract GSPStorage is ReentrancyGuard {
// ============ Core Address ============
// _MAINTAINER_ is the maintainer of GSP
address public _MAINTAINER_;
// _ADMIN_ can set price
address public _ADMIN_;
// _BASE_TOKEN_ and _QUOTE_TOKEN_ should be ERC20 token
IERC20 public _BASE_TOKEN_;
IERC20 public _QUOTE_TOKEN_;
Expand Down
13 changes: 9 additions & 4 deletions contracts/GasSavingPool/impl/GSPVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ contract GSPVault is GSPStorage {
_;
}

/// @notice Check whether the caller is admin
modifier onlyAdmin() {
require(msg.sender == _ADMIN_, "ADMIN_ACCESS_DENIED");
_;
}

// ============ Events ============

event Transfer(address indexed from, address indexed to, uint256 amount);
Expand Down Expand Up @@ -133,17 +139,16 @@ contract GSPVault is GSPStorage {
* @dev The default priceLimit is 1e3, the decimals of priceLimit is 1e6
* @param priceLimit The new price limit
*/
function adjustPriceLimit(uint256 priceLimit) external onlyMaintainer {
function adjustPriceLimit(uint256 priceLimit) external onlyAdmin {
// the default priceLimit is 1e3
require(priceLimit <= 1e6, "INVALID_PRICE_LIMIT");
_PRICE_LIMIT_ = priceLimit;
}

/**
* @notice Adjust oricle price i, only for maintainer
* @param i The new oracle price
* @notice Adjust oricle price i, only for admin
*/
function adjustPrice(uint256 i) external onlyMaintainer {
function adjustPrice(uint256 i) external onlyAdmin {
// the difference between i and _I_ should be less than priceLimit
uint256 offset = i > _I_ ? i - _I_ : _I_ - i;
require((offset * 1e6 / _I_) <= _PRICE_LIMIT_, "EXCEED_PRICE_LIMIT");
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"name": "combination-pizza-hut-and-taco-bell",
"name": "dodo-gassaving-pool",
"version": "1.0.0",
"main": "index.js",
"repository": "git@cache:cachemonet0x0CF6619/houndry.git",
"author": "cachemonet0x0CF6619 <[email protected]>",
"repository": "git@github.com:DODOEX/dodo-gassaving-pool.git",
"author": "dodo",
"license": "MIT",
"scripts": {
"lint": "solhint 'src/**/*.sol'",
Expand Down
23 changes: 23 additions & 0 deletions scripts/DeployGSP.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ contract DeployGSP is Script {

// Init params
address constant MAINTAINER = 0x95C4F5b83aA70810D4f142d58e5F7242Bd891CB0;
address constant ADMIN = address(1); // todo change
address constant BASE_TOKEN_ADDRESS = DAI;
address constant QUOTE_TOKEN_ADDRESS = USDC;
uint256 constant LP_FEE_RATE = 0;
Expand All @@ -32,6 +33,27 @@ contract DeployGSP is Script {
// init GSP
gsp.init(
MAINTAINER,
MAINTAINER,
BASE_TOKEN_ADDRESS,
QUOTE_TOKEN_ADDRESS,
LP_FEE_RATE,
MT_FEE_RATE,
I,
K,
IS_OPEN_TWAP
);

return gsp;
}

function runAdminDiff() public returns (GSP){
// Deploy GSP
gsp = new GSP();

// init GSP
gsp.init(
MAINTAINER,
ADMIN,
BASE_TOKEN_ADDRESS,
QUOTE_TOKEN_ADDRESS,
LP_FEE_RATE,
Expand All @@ -44,5 +66,6 @@ contract DeployGSP is Script {
return gsp;
}


function testSuccess() public {}
}
2 changes: 1 addition & 1 deletion scripts/StableSwap.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ contract StableSwap is Script {

address constant UniV3_ROUTER = 0xE592427A0AEce92De3Edee1F18E0157C05861564;
address constant USDC_WHALE = 0x51eDF02152EBfb338e03E30d65C15fBf06cc9ECC;
address constant DAI_WHALE = 0x25B313158Ce11080524DcA0fD01141EeD5f94b81;
address constant DAI_WHALE = 0x40ec5B33f54e0E8A33A975908C5BA1c14e5BbbDf;
address LP = vm.addr(1);

DeployGSP deployGSP = new DeployGSP();
Expand Down
1 change: 1 addition & 0 deletions test/GPSTrader.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ contract TestGSPTrader is Test {
function testUpdateTargetOverflow() public {
GSP gspTest = new GSP();
gspTest.init(
MAINTAINER,
MAINTAINER,
address(mockBaseToken),
address(mockQuoteToken),
Expand Down
6 changes: 6 additions & 0 deletions test/GSP.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ contract TestGSPVault is Test {
bool IS_OPEN_TWAP = false;

gsp.init(
MAINTAINER,
MAINTAINER,
BASE_TOKEN_ADDRESS,
QUOTE_TOKEN_ADDRESS,
Expand Down Expand Up @@ -83,6 +84,7 @@ contract TestGSPVault is Test {

vm. expectRevert("BASE_QUOTE_CAN_NOT_BE_SAME");
gsp.init(
MAINTAINER,
MAINTAINER,
BASE_TOKEN_ADDRESS,
BASE_TOKEN_ADDRESS,
Expand All @@ -95,6 +97,7 @@ contract TestGSPVault is Test {
// I is invalid
vm. expectRevert();
gsp.init(
MAINTAINER,
MAINTAINER,
BASE_TOKEN_ADDRESS,
QUOTE_TOKEN_ADDRESS,
Expand All @@ -107,6 +110,7 @@ contract TestGSPVault is Test {
// K is invalid
vm. expectRevert();
gsp.init(
MAINTAINER,
MAINTAINER,
BASE_TOKEN_ADDRESS,
QUOTE_TOKEN_ADDRESS,
Expand All @@ -119,6 +123,7 @@ contract TestGSPVault is Test {

// Init twice
gsp.init(
MAINTAINER,
MAINTAINER,
BASE_TOKEN_ADDRESS,
QUOTE_TOKEN_ADDRESS,
Expand All @@ -130,6 +135,7 @@ contract TestGSPVault is Test {
);
vm.expectRevert("GSP_INITIALIZED");
gsp.init(
MAINTAINER,
MAINTAINER,
BASE_TOKEN_ADDRESS,
QUOTE_TOKEN_ADDRESS,
Expand Down
14 changes: 10 additions & 4 deletions test/GSPVault.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ contract TestGSPVault is Test {

// Init Params
address constant MAINTAINER = 0x95C4F5b83aA70810D4f142d58e5F7242Bd891CB0;
address constant ADMIN = address(1);
uint256 constant LP_FEE_RATE = 0;
uint256 constant MT_FEE_RATE = 10000000000000;
uint256 constant I = 1000000;
Expand All @@ -38,7 +39,7 @@ contract TestGSPVault is Test {
function setUp() public {
// Deploy and Init
DeployGSP deployGSP = new DeployGSP();
gsp = deployGSP.run();
gsp = deployGSP.runAdminDiff();

// Deploy ERC20 Mock
mockBaseToken = new MockERC20("mockBaseToken", "mockBaseToken", 18);
Expand All @@ -60,7 +61,7 @@ contract TestGSPVault is Test {
}

function testOnlyMaintainerCanAdjustParams() public {
vm.startPrank(MAINTAINER);
vm.startPrank(ADMIN);
// adjust price limit
gsp.adjustPriceLimit(1e4);
assertEq(gsp._PRICE_LIMIT_(), 1e4);
Expand All @@ -71,10 +72,12 @@ contract TestGSPVault is Test {
gsp.adjustPrice((1e6 + 1e4));
uint256 priceAfter = gsp._I_();
assertTrue(priceAfter == (1e6 + 1e4));
vm.stopPrank();

// adjust mtfee rate
uint256 mtFeeRateBefore = gsp._MT_FEE_RATE_();
assertTrue(mtFeeRateBefore == MT_FEE_RATE);
vm.prank(MAINTAINER);
gsp.adjustMtFeeRate(2e13);
uint256 mtFeeRateAfter = gsp._MT_FEE_RATE_();
assertTrue(mtFeeRateAfter == 2e13);
Expand All @@ -83,6 +86,7 @@ contract TestGSPVault is Test {
function testSyncSucceed() public {
GSP gspTest = new GSP();
gspTest.init(
MAINTAINER,
MAINTAINER,
address(mockBaseToken),
address(mockQuoteToken),
Expand All @@ -105,6 +109,7 @@ contract TestGSPVault is Test {
function testSyncOverflow() public {
GSP gspTest = new GSP();
gspTest.init(
MAINTAINER,
MAINTAINER,
address(mockBaseToken),
address(mockQuoteToken),
Expand Down Expand Up @@ -277,13 +282,13 @@ contract TestGSPVault is Test {


function testAdjustPriceLimitIsInvalid() public{
vm.startPrank(MAINTAINER);
vm.startPrank(ADMIN);
vm.expectRevert("INVALID_PRICE_LIMIT");
gsp.adjustPriceLimit(1e7);
}

function testAdjustPriceExceedPriceLimit() public{
vm.startPrank(MAINTAINER);
vm.startPrank(ADMIN);
vm.expectRevert("EXCEED_PRICE_LIMIT");
gsp.adjustPrice((2e6));
}
Expand Down Expand Up @@ -340,6 +345,7 @@ contract TestGSPVault is Test {
function testShouldNotBeZero() public {
GSP gspTest = new GSP();
gspTest.init(
MAINTAINER,
MAINTAINER,
address(mockBaseToken),
address(mockQuoteToken),
Expand Down

0 comments on commit a634be3

Please sign in to comment.