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

Configuration scripts for new deployments #612

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 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
8 changes: 8 additions & 0 deletions addresses/context/arbitrum.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,13 @@
{
"address": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
"name": "WETH"
},
{
"address": "0xaf88d065e77c8cc2239327c5edb3a432268e5831",
"name": "USDC"
},
{
"address": "0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9",
"name": "USDT"
}
]
18 changes: 12 additions & 6 deletions script/core/ActivateMarket.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {ActivateSemibook} from "./ActivateSemibook.s.sol";
TKN1_IN_GWEI=$(cast --to-wei $(bc -l <<< 1/$NATIVE_IN_USDC) gwei) \
TKN2_IN_GWEI=$(cast --to-wei $(bc -l <<< 1/$NATIVE_IN_ETH) gwei) \
FEE=30 \
COVER_FACTOR=1000 \
forge script --fork-url mumbai ActivateMarket*/

contract ActivateMarket is Deployer {
Expand All @@ -25,7 +26,8 @@ contract ActivateMarket is Deployer {
tkn2: IERC20(envAddressOrName("TKN2")),
tkn1_in_gwei: vm.envUint("TKN1_IN_GWEI"),
tkn2_in_gwei: vm.envUint("TKN2_IN_GWEI"),
fee: vm.envUint("FEE")
fee: vm.envUint("FEE"),
coverFactor: vm.envUint("COVER_FACTOR")
});
}

Expand Down Expand Up @@ -54,10 +56,11 @@ contract ActivateMarket is Deployer {
IERC20 tkn2,
uint tkn1_in_gwei,
uint tkn2_in_gwei,
uint fee
uint fee,
uint coverFactor
) public {
(MgvStructs.GlobalPacked global,) = mgv.config(address(0), address(0));
innerRun(mgv, global.gasprice(), reader, tkn1, tkn2, tkn1_in_gwei, tkn2_in_gwei, fee);
innerRun(mgv, global.gasprice(), reader, tkn1, tkn2, tkn1_in_gwei, tkn2_in_gwei, fee, coverFactor);
}

/**
Expand All @@ -72,15 +75,17 @@ contract ActivateMarket is Deployer {
IERC20 tkn2,
uint tkn1_in_gwei,
uint tkn2_in_gwei,
uint fee
uint fee,
uint coverFactor
) public {
new ActivateSemibook().innerRun({
mgv: mgv,
gaspriceOverride: gaspriceOverride,
outbound_tkn: tkn1,
inbound_tkn: tkn2,
outbound_in_gwei: tkn1_in_gwei,
fee: fee
fee: fee,
coverFactor: coverFactor
});

new ActivateSemibook().innerRun({
Expand All @@ -89,7 +94,8 @@ contract ActivateMarket is Deployer {
outbound_tkn: tkn2,
inbound_tkn: tkn1,
outbound_in_gwei: tkn2_in_gwei,
fee: fee
fee: fee,
coverFactor: coverFactor
});

new UpdateMarket().innerRun({tkn0: tkn1, tkn1: tkn2, reader: reader});
Expand Down
94 changes: 60 additions & 34 deletions script/core/ActivateSemibook.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import {Mangrove} from "mgv_src/Mangrove.sol";
import {IERC20} from "mgv_src/IERC20.sol";
import {MgvStructs} from "mgv_src/MgvLib.sol";

uint constant COVER_FACTOR = 1000;

/*
Activates a semibook on mangrove.
outbound: outbound token
Expand All @@ -22,20 +20,61 @@ uint constant COVER_FACTOR = 1000;
2. Multiply by 10^9
3. Round to nearest integer*/

contract ActivateSemibook is Test2, Deployer {
contract ActivateUtils is Test2 {
function measureTransferGas(IERC20 tkn) public returns (uint) {
address someone = freshAddress();
deal(address(tkn), someone, 10);
vm.prank(someone);
tkn.approve(address(this), type(uint).max);
/* WARNING: gas metering is done by local execution, which means that on
* networks that have different EIPs activated, there will be discrepancies. */
uint post;
uint pre = gasleft();
tkn.transferFrom(someone, address(this), 1);
post = gasleft();
return pre - post;
}

function evaluateGasbase(IERC20 outbound_tkn, IERC20 inbound_tkn) public returns (uint gasbase) {
uint outbound_gas = measureTransferGas(outbound_tkn);
uint inbound_gas = measureTransferGas(inbound_tkn);
gasbase = 2 * (outbound_gas + inbound_gas);
}

function evaluateDensity(IERC20 outbound_tkn, uint coverFactor, uint gasprice, uint outbound_in_gwei)
public
view
returns (uint density)
{
uint outbound_decimals = outbound_tkn.decimals();
density = (coverFactor * gasprice * 10 ** outbound_decimals) / outbound_in_gwei;
// min density of at least 1 wei of outbound token
density = density == 0 ? 1 : density;
}
}

contract ActivateSemibook is Deployer, ActivateUtils {
function run() public {
innerRun({
mgv: Mangrove(envAddressOrName("MGV", "Mangrove")),
outbound_tkn: IERC20(envAddressOrName("OUTBOUND_TKN")),
inbound_tkn: IERC20(envAddressOrName("INBOUND_TKN")),
outbound_in_gwei: vm.envUint("OUTBOUND_IN_GWEI"),
fee: vm.envUint("FEE")
fee: vm.envUint("FEE"),
coverFactor: vm.envUint("COVER_FACTOR")
});
}

function innerRun(Mangrove mgv, IERC20 outbound_tkn, IERC20 inbound_tkn, uint outbound_in_gwei, uint fee) public {
function innerRun(
Mangrove mgv,
IERC20 outbound_tkn,
IERC20 inbound_tkn,
uint outbound_in_gwei,
uint fee,
uint coverFactor
) public {
(MgvStructs.GlobalPacked global,) = mgv.config(address(0), address(0));
innerRun(mgv, global.gasprice(), outbound_tkn, inbound_tkn, outbound_in_gwei, fee);
innerRun(mgv, global.gasprice(), outbound_tkn, inbound_tkn, outbound_in_gwei, fee, coverFactor);
}

function innerRun(
Expand All @@ -44,7 +83,8 @@ contract ActivateSemibook is Test2, Deployer {
IERC20 outbound_tkn,
IERC20 inbound_tkn,
uint outbound_in_gwei,
uint fee
uint fee,
uint coverFactor
) public {
/*

Expand All @@ -53,32 +93,32 @@ contract ActivateSemibook is Test2, Deployer {
sequence.

*/
uint outbound_gas = measureTransferGas(outbound_tkn);
uint inbound_gas = measureTransferGas(inbound_tkn);
uint gasbase = 2 * (outbound_gas + inbound_gas);
uint gasbase = evaluateGasbase(outbound_tkn, inbound_tkn);
console.log("Measured gasbase: %d", gasbase);

/*

The density is the minimal amount of tokens bought per unit of gas spent.
The heuristic is: The gas cost of executing an order should represent at
most 1/COVER_FACTOR the value being bought. In other words: multiply the
most 1/coverFactor the value being bought. In other words: multiply the
price of gas in tokens (obtained from the price of gas in gwei and the price
of tokens in gwei) by COVER_FACTOR to get the density.
of tokens in gwei) by coverFactor to get the density.

Units:
- outbound_in_gwei is in gwei/display token units
- COVER_FACTOR is unitless
- outbound_in_gwei is in gwei of native token/display token units
- coverFactor is unitless
- decN is in (base token units)/(display token units)
- global.gasprice() is in gwei/gas
- so density is in (base token units token)/gas
*/
uint outbound_decimals = outbound_tkn.decimals();
uint density = (COVER_FACTOR * gaspriceOverride * 10 ** outbound_decimals) / outbound_in_gwei;
// min density of at least 1 wei of outbound token
density = density == 0 ? 1 : density;
console.log("With gasprice: %d gwei, cover factor:%d", gaspriceOverride, COVER_FACTOR);
console.log("Derived density %s %s per gas unit", toFixed(density, outbound_decimals), outbound_tkn.symbol());
uint density = evaluateDensity(outbound_tkn, coverFactor, gaspriceOverride, outbound_in_gwei);
console.log("With gasprice: %d gwei, cover factor:%d", gaspriceOverride, coverFactor);
console.log(
"Derived density %d (%s %s per gas unit)",
density,
toFixed(density, outbound_tkn.decimals()),
outbound_tkn.symbol()
);

broadcast();
mgv.activate({
Expand All @@ -89,18 +129,4 @@ contract ActivateSemibook is Test2, Deployer {
offer_gasbase: gasbase
});
}

function measureTransferGas(IERC20 tkn) internal returns (uint) {
address someone = freshAddress();
vm.prank(someone);
tkn.approve(address(this), type(uint).max);
deal(address(tkn), someone, 10);
/* WARNING: gas metering is done by local execution, which means that on
* networks that have different EIPs activated, there will be discrepancies. */
uint post;
uint pre = gasleft();
tkn.transferFrom(someone, address(this), 1);
post = gasleft();
return pre - post;
}
}
56 changes: 56 additions & 0 deletions script/deployers/EvalMarketParameters.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.13;

import {ToyENS} from "mgv_lib/ToyENS.sol";

import {Deployer} from "mgv_script/lib/Deployer.sol";

import {ActivateUtils, IERC20} from "mgv_script/core/ActivateSemibook.s.sol";

import {console} from "forge-std/console.sol";

/**
* This scripts logs gasbase and density suggested values in order to activate the (TOKEN0, TOKEN1) market using a gasprice override to compute density
*
* TOKEN0 the name of the first token
* TOKEN1 the name of the second token
* NATIVE_IN_USD the price of a native token in USD with fixed decimals precision (say n)
* TOKEN[0/1]_IN_USD the price of token[0/1] in USD with the n decimals precision
* GASPRICE_OVERRIDE is the gasprice (in gwei) to consider to compute density
* COVER_FACTOR to compute density, i.e density =
*
*
* usage with Native token being AETH (with n=1):
* GASPRICE_OVERRIDE=1 NATIVE_IN_USD=1600 TOKEN0=USDC TOKEN1=USDT TOKEN0_IN_USD=1 TOKEN1_IN_USD=1 COVER_FACTOR=100 forge script EvalMarketParameters --fork-url arbitrum
*/

contract EvalMarketParameters is Deployer, ActivateUtils {
uint nativePrice;
jkrivine marked this conversation as resolved.
Show resolved Hide resolved

function run() public {
nativePrice = vm.envUint("NATIVE_IN_USD");
uint gaspriceOverride = vm.envUint("GASPRICE_OVERRIDE");
IERC20 token0 = IERC20(envAddressOrName("TOKEN0"));
IERC20 token1 = IERC20(envAddressOrName("TOKEN1"));
uint price0 = vm.envUint("TOKEN0_IN_USD");
uint price1 = vm.envUint("TOKEN1_IN_USD");
uint coverFactor = vm.envUint("COVER_FACTOR");

innerRun(token0, token1, price0, price1, gaspriceOverride, coverFactor);
jkrivine marked this conversation as resolved.
Show resolved Hide resolved
}

function toGweiOfNative(uint price) internal view returns (uint) {
return (price * 10 ** 9) / nativePrice;
}

function innerRun(IERC20 token0, IERC20 token1, uint price0, uint price1, uint gaspriceOverride, uint coverFactor)
public
{
uint gasbase = evaluateGasbase(token0, token1);
console.log("gasbase:", gasbase);
uint density0 = evaluateDensity(token0, coverFactor, gaspriceOverride, toGweiOfNative(price0));
console.log("density for outbound %s: %d", token0.symbol(), density0);
uint density1 = evaluateDensity(token1, coverFactor, gaspriceOverride, toGweiOfNative(price1));
console.log("density for outbound %s: %d", token1.symbol(), density1);
}
}
3 changes: 2 additions & 1 deletion script/deployers/MumbaiActivateMarket.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ contract MumbaiActivateMarket is Deployer {
tkn2: token1,
tkn1_in_gwei: toGweiOfMatic(price0),
tkn2_in_gwei: toGweiOfMatic(price1),
fee: 0
fee: 0,
coverFactor: 1000
});

new ActivateMangroveOrder().innerRun({
Expand Down
9 changes: 6 additions & 3 deletions script/deployers/MumbaiMangroveFullTestnetDeployer.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ contract MumbaiMangroveFullTestnetDeployer is Deployer {
tkn2: usdc,
tkn1_in_gwei: toGweiOfMatic(prices[0]),
tkn2_in_gwei: toGweiOfMatic(prices[1]),
fee: 0
fee: 0,
coverFactor: 1000
});
new ActivateMarket().innerRun({
mgv: mgv,
Expand All @@ -91,7 +92,8 @@ contract MumbaiMangroveFullTestnetDeployer is Deployer {
tkn2: dai,
tkn1_in_gwei: toGweiOfMatic(prices[2]),
tkn2_in_gwei: toGweiOfMatic(prices[0]),
fee: 0
fee: 0,
coverFactor: 1000
});
new ActivateMarket().innerRun({
mgv: mgv,
Expand All @@ -101,7 +103,8 @@ contract MumbaiMangroveFullTestnetDeployer is Deployer {
tkn2: usdc,
tkn1_in_gwei: toGweiOfMatic(prices[2]),
tkn2_in_gwei: toGweiOfMatic(prices[1]),
fee: 0
fee: 0,
coverFactor: 1000
});

// Activate MangroveOrder on markets
Expand Down
8 changes: 4 additions & 4 deletions script/toy/MangroveJs.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,10 @@ contract MangroveJsDeploy is Deployer {

ActivateMarket activateMarket = new ActivateMarket();

activateMarket.innerRun(mgv, mgvReader, tokenA, tokenB, 2 * 1e9, 3 * 1e9, 0);
activateMarket.innerRun(mgv, mgvReader, dai, usdc, 1e9 / 1000, 1e9 / 1000, 0);
activateMarket.innerRun(mgv, mgvReader, weth, dai, 1e9, 1e9 / 1000, 0);
activateMarket.innerRun(mgv, mgvReader, weth, usdc, 1e9, 1e9 / 1000, 0);
activateMarket.innerRun(mgv, mgvReader, tokenA, tokenB, 2 * 1e9, 3 * 1e9, 0, 1000);
activateMarket.innerRun(mgv, mgvReader, dai, usdc, 1e9 / 1000, 1e9 / 1000, 0, 1000);
activateMarket.innerRun(mgv, mgvReader, weth, dai, 1e9, 1e9 / 1000, 0, 1000);
activateMarket.innerRun(mgv, mgvReader, weth, usdc, 1e9, 1e9 / 1000, 0, 1000);

MangroveOrderDeployer mgoeDeployer = new MangroveOrderDeployer();
mgoeDeployer.innerRun({admin: broadcaster(), mgv: IMangrove(payable(mgv))});
Expand Down