Skip to content

Commit

Permalink
Merge the develop branch into the master branch, v1.2.0
Browse files Browse the repository at this point in the history
This merge contains the following set of changes:
  - Zero farm value in stat() for low yield values (#72)
  - Customizable zkBob pools for different tokens (#66)
  • Loading branch information
akolotov committed Jun 20, 2023
2 parents 4af3322 + e7e2255 commit 74f6c31
Show file tree
Hide file tree
Showing 28 changed files with 903 additions and 834 deletions.
14 changes: 10 additions & 4 deletions script/scripts/Env.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ pragma solidity 0.8.15;

import "forge-std/Script.sol";

enum PoolType {
BOB,
ETH,
USDC,
ERC20
}

// common
address constant deployer = 0x39F0bD56c1439a22Ee90b4972c16b7868D161981;
address constant admin = 0xd4a3D9Ca00fa1fD8833D560F9217458E61c446d8;
Expand All @@ -17,7 +24,9 @@ bytes32 constant bobSalt = bytes32(uint256(285834900769));

// zkbob
uint256 constant zkBobPoolId = 0; // 0 is reserved for Polygon MVP pool, do not use for other deployments
PoolType constant zkBobPoolType = PoolType.BOB;
string constant zkBobVerifiers = "prodV1";
address constant zkBobToken = 0xB0B195aEFA3650A6908f15CdaC7D92F8a5791B0B;
uint256 constant zkBobInitialRoot = 11469701942666298368112882412133877458305516134926649826543144744382391691533;
address constant zkBobRelayer = 0xc2c4AD59B78F4A0aFD0CDB8133E640Db08Fa5b90;
address constant zkBobRelayerFeeReceiver = 0x758768EC473279c4B1Aa61FA5450745340D4B17d;
Expand All @@ -31,6 +40,7 @@ uint256 constant zkBobDailyUserDirectDepositCap = 0;
uint256 constant zkBobDirectDepositCap = 0;
uint256 constant zkBobDirectDepositFee = 0.1 gwei;
uint256 constant zkBobDirectDepositTimeout = 1 days;
address constant permit2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;

// new zkbob impl
address constant zkBobPool = 0x72e6B59D4a90ab232e55D4BB7ed2dD17494D62fB;
Expand All @@ -52,7 +62,3 @@ address constant uniV3Quoter = 0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6;
uint24 constant fee0 = 500;
address constant usdc = 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174;
uint24 constant fee1 = 500;

// zkbobpool eth
address constant weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address constant permit2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;
9 changes: 4 additions & 5 deletions script/scripts/Local.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import "./Env.s.sol";
import "../../test/shared/EIP2470.t.sol";
import "../../src/BobToken.sol";
import "../../src/proxy/EIP1967Proxy.sol";
import "../../src/zkbob/ZkBobPool.sol";
import "../../src/zkbob/ZkBobPoolERC20.sol";
import "../../src/zkbob/ZkBobPoolBOB.sol";
import "../../src/zkbob/manager/MutableOperatorManager.sol";
import "../../src/zkbob/ZkBobDirectDepositQueue.sol";

Expand Down Expand Up @@ -44,7 +43,7 @@ contract DeployLocal is Script {
EIP1967Proxy poolProxy = new EIP1967Proxy(tx.origin, mockImpl, "");
EIP1967Proxy queueProxy = new EIP1967Proxy(tx.origin, mockImpl, "");

ZkBobPoolERC20 poolImpl = new ZkBobPoolERC20(
ZkBobPoolBOB poolImpl = new ZkBobPoolBOB(
zkBobPoolId,
address(bob),
transferVerifier,
Expand All @@ -66,9 +65,9 @@ contract DeployLocal is Script {
);
poolProxy.upgradeToAndCall(address(poolImpl), initData);
}
ZkBobPoolERC20 pool = ZkBobPoolERC20(address(poolProxy));
ZkBobPoolBOB pool = ZkBobPoolBOB(address(poolProxy));

ZkBobDirectDepositQueue queueImpl = new ZkBobDirectDepositQueue(address(pool), address(bob));
ZkBobDirectDepositQueue queueImpl = new ZkBobDirectDepositQueue(address(pool), address(bob), 1_000_000_000);
queueProxy.upgradeTo(address(queueImpl));
ZkBobDirectDepositQueue queue = ZkBobDirectDepositQueue(address(queueProxy));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,15 @@ pragma solidity 0.8.15;

import "forge-std/Script.sol";
import "./Env.s.sol";
import "../../src/proxy/EIP1967Proxy.sol";
import "../../src/zkbob/ZkBobPool.sol";
import "../../src/zkbob/manager/MutableOperatorManager.sol";
import "../../src/zkbob/ZkBobPoolERC20.sol";
import "../../src/zkbob/ZkBobPoolBOB.sol";

contract DeployNewZkBobPoolERC20Impl is Script {
contract DeployNewZkBobPoolBOBImpl is Script {
function run() external {
vm.startBroadcast();

ZkBobPoolERC20 pool = ZkBobPoolERC20(zkBobPool);
ZkBobPoolBOB pool = ZkBobPoolBOB(zkBobPool);

ZkBobPoolERC20 impl = new ZkBobPoolERC20(
ZkBobPoolBOB impl = new ZkBobPoolBOB(
pool.pool_id(),
pool.token(),
pool.transfer_verifier(),
Expand Down
3 changes: 0 additions & 3 deletions script/scripts/NewZkBobPoolETHImpl.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ pragma solidity 0.8.15;

import "forge-std/Script.sol";
import "./Env.s.sol";
import "../../src/proxy/EIP1967Proxy.sol";
import "../../src/zkbob/ZkBobPool.sol";
import "../../src/zkbob/manager/MutableOperatorManager.sol";
import "../../src/zkbob/ZkBobPoolETH.sol";

contract DeployNewZkBobPoolETHImpl is Script {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ pragma solidity 0.8.15;
import "forge-std/Script.sol";
import "./Env.s.sol";
import "../../src/proxy/EIP1967Proxy.sol";
import "../../src/zkbob/ZkBobPool.sol";
import "../../src/zkbob/ZkBobDirectDepositQueue.sol";
import "../../src/zkbob/ZkBobDirectDepositQueueETH.sol";
import "../../src/zkbob/manager/MutableOperatorManager.sol";
import "../../src/zkbob/ZkBobPoolBOB.sol";
import "../../src/zkbob/ZkBobPoolETH.sol";
import "../../src/zkbob/ZkBobPoolUSDC.sol";
import "../../src/zkbob/ZkBobPoolERC20.sol";

contract DeployZkBobPoolERC20 is Script {
contract DeployZkBobPool is Script {
function run() external {
vm.startBroadcast();

Expand All @@ -33,14 +36,39 @@ contract DeployZkBobPoolERC20 is Script {
EIP1967Proxy poolProxy = new EIP1967Proxy(tx.origin, mockImpl, "");
EIP1967Proxy queueProxy = new EIP1967Proxy(tx.origin, mockImpl, "");

ZkBobPoolERC20 poolImpl = new ZkBobPoolERC20(
zkBobPoolId,
bobVanityAddr,
transferVerifier,
treeVerifier,
batchDepositVerifier,
address(queueProxy)
);
ZkBobPool poolImpl;
if (zkBobPoolType == PoolType.ETH) {
poolImpl = new ZkBobPoolETH(
zkBobPoolId, zkBobToken,
transferVerifier, treeVerifier, batchDepositVerifier,
address(queueProxy), permit2
);
} else if (zkBobPoolType == PoolType.BOB) {
poolImpl = new ZkBobPoolBOB(
zkBobPoolId, zkBobToken,
transferVerifier, treeVerifier, batchDepositVerifier,
address(queueProxy)
);
} else if (zkBobPoolType == PoolType.USDC) {
poolImpl = new ZkBobPoolUSDC(
zkBobPoolId, zkBobToken,
transferVerifier, treeVerifier, batchDepositVerifier,
address(queueProxy)
);
} else if (zkBobPoolType == PoolType.ERC20) {
uint8 decimals = IERC20Metadata(zkBobToken).decimals();
uint256 denominator = decimals > 9 ? 10 ** (decimals - 9) : 1;
uint256 precision = decimals > 9 ? 1_000_000_000 : 10 ** decimals;
poolImpl = new ZkBobPoolERC20(
zkBobPoolId, zkBobToken,
transferVerifier, treeVerifier, batchDepositVerifier,
address(queueProxy), permit2,
denominator, precision
);
} else {
revert("Unknown pool type");
}

bytes memory initData = abi.encodeWithSelector(
ZkBobPool.initialize.selector,
zkBobInitialRoot,
Expand All @@ -53,9 +81,14 @@ contract DeployZkBobPoolERC20 is Script {
zkBobDirectDepositCap
);
poolProxy.upgradeToAndCall(address(poolImpl), initData);
ZkBobPoolERC20 pool = ZkBobPoolERC20(address(poolProxy));
ZkBobPool pool = ZkBobPool(address(poolProxy));

ZkBobDirectDepositQueue queueImpl = new ZkBobDirectDepositQueue(address(pool), bobVanityAddr);
ZkBobDirectDepositQueue queueImpl;
if (zkBobPoolType == PoolType.ETH) {
queueImpl = new ZkBobDirectDepositQueueETH(address(pool), zkBobToken, pool.denominator());
} else {
queueImpl = new ZkBobDirectDepositQueue(address(pool), zkBobToken, pool.denominator());
}
queueProxy.upgradeTo(address(queueImpl));
ZkBobDirectDepositQueue queue = ZkBobDirectDepositQueue(address(queueProxy));

Expand Down
98 changes: 0 additions & 98 deletions script/scripts/ZkBobPoolETH.s.sol

This file was deleted.

6 changes: 5 additions & 1 deletion src/BobVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,11 @@ contract BobVault is EIP1967Admin, Ownable, YieldConnector {
res.total += _delegateInvestedAmount(yield, _token);
res.required += dust;
}
res.farmed = res.total - res.required;
if (res.required >= res.total) {
res.farmed = 0;
} else {
res.farmed = res.total - res.required;
}
}

/**
Expand Down
18 changes: 18 additions & 0 deletions src/interfaces/IUSDCPermit.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: CC0-1.0

pragma solidity 0.8.15;

interface IUSDCPermit {
function transferWithAuthorization(
address from,
address to,
uint256 value,
uint256 validAfter,
uint256 validBefore,
bytes32 nonce,
uint8 v,
bytes32 r,
bytes32 s
)
external;
}
9 changes: 0 additions & 9 deletions src/utils/Sacrifice.sol

This file was deleted.

13 changes: 9 additions & 4 deletions src/utils/UniswapV3Seller.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import "@uniswap/v3-periphery/contracts/interfaces/IPeripheryImmutableState.sol"
import "@uniswap/v3-periphery/contracts/interfaces/IQuoter.sol";
import "@uniswap/v3-periphery/contracts/interfaces/external/IWETH9.sol";
import "../interfaces/ITokenSeller.sol";
import "./Sacrifice.sol";

/**
* @title UniswapV3Seller
Expand Down Expand Up @@ -56,7 +55,9 @@ contract UniswapV3Seller is ITokenSeller {

uint256 amountOut = swapRouter.exactInput(
ISwapRouter.ExactInputParams({
path: abi.encodePacked(token0, fee0, token1, fee1, WETH),
path: token1 == address(0)
? abi.encodePacked(token0, fee0, WETH)
: abi.encodePacked(token0, fee0, token1, fee1, WETH),
recipient: address(this),
deadline: block.timestamp,
amountIn: _amount,
Expand All @@ -65,7 +66,8 @@ contract UniswapV3Seller is ITokenSeller {
);
WETH.withdraw(amountOut);
if (!payable(_receiver).send(amountOut)) {
new Sacrifice{value: amountOut}(_receiver);
WETH.deposit{value: amountOut}();
WETH.transfer(_receiver, amountOut);
}
uint256 remainingBalance = IERC20(token0).balanceOf(address(this));
if (remainingBalance + _amount > balance) {
Expand All @@ -82,6 +84,9 @@ contract UniswapV3Seller is ITokenSeller {
* @return received eth amount.
*/
function quoteSellForETH(uint256 _amount) external returns (uint256) {
return quoter.quoteExactInput(abi.encodePacked(token0, fee0, token1, fee1, WETH), _amount);
bytes memory path = token1 == address(0)
? abi.encodePacked(token0, fee0, WETH)
: abi.encodePacked(token0, fee0, token1, fee1, WETH);
return quoter.quoteExactInput(path, _amount);
}
}
6 changes: 4 additions & 2 deletions src/zkbob/ZkBobDirectDepositQueue.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ contract ZkBobDirectDepositQueue is IZkBobDirectDeposits, IZkBobDirectDepositQue
using SafeERC20 for IERC20;

uint256 internal constant R = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
uint256 internal constant TOKEN_DENOMINATOR = 1_000_000_000;
uint256 internal constant MAX_NUMBER_OF_DIRECT_DEPOSITS = 16;
bytes4 internal constant MESSAGE_PREFIX_DIRECT_DEPOSIT_V1 = 0x00000001;

uint256 internal immutable TOKEN_DENOMINATOR;

address public immutable token;
uint256 public immutable pool_id;
address public immutable pool;
Expand All @@ -50,10 +51,11 @@ contract ZkBobDirectDepositQueue is IZkBobDirectDeposits, IZkBobDirectDepositQue
event RefundDirectDeposit(uint256 indexed nonce, address receiver, uint256 amount);
event CompleteDirectDepositBatch(uint256[] indices);

constructor(address _pool, address _token) {
constructor(address _pool, address _token, uint256 _denominator) {
require(Address.isContract(_token), "ZkBobDirectDepositQueue: not a contract");
pool = _pool;
token = _token;
TOKEN_DENOMINATOR = _denominator;
pool_id = uint24(IZkBobPool(_pool).pool_id());
}

Expand Down
Loading

0 comments on commit 74f6c31

Please sign in to comment.