Skip to content

Commit

Permalink
chore: merge dev
Browse files Browse the repository at this point in the history
  • Loading branch information
wei3erHase committed Jul 23, 2024
2 parents 45814ef + dad92aa commit 58bd01d
Show file tree
Hide file tree
Showing 53 changed files with 2,599 additions and 2,099 deletions.
2 changes: 1 addition & 1 deletion .forge-snapshots/newBCoWFactory.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4889580
4899289
2 changes: 1 addition & 1 deletion .forge-snapshots/newBCoWPool.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4033896
4042925
2 changes: 1 addition & 1 deletion .forge-snapshots/newBFactory.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4130621
4140477
2 changes: 1 addition & 1 deletion .forge-snapshots/newBPool.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3477592
3486610
2 changes: 1 addition & 1 deletion .forge-snapshots/swapExactAmountIn.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
104914
104920
2 changes: 1 addition & 1 deletion .forge-snapshots/swapExactAmountInInverse.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
114583
114589
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"@cowprotocol/contracts": "github:cowprotocol/contracts.git#a10f40788a",
"@openzeppelin/contracts": "5.0.2",
"composable-cow": "github:cowprotocol/composable-cow.git#24d556b",
"cow-amm": "github:cowprotocol/cow-amm.git#6566128",
"solmate": "github:transmissions11/solmate#c892309"
},
"devDependencies": {
Expand Down
3 changes: 3 additions & 0 deletions remappings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ solmate/=node_modules/solmate/src
@cowprotocol/=node_modules/@cowprotocol/contracts/src/contracts
cowprotocol/=node_modules/@cowprotocol/contracts/src/
@composable-cow/=node_modules/composable-cow/
@cow-amm/=node_modules/cow-amm/src
lib/openzeppelin/=node_modules/@openzeppelin

contracts/=src/contracts
interfaces/=src/interfaces
libraries/=src/libraries
125 changes: 125 additions & 0 deletions src/contracts/BCoWHelper.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.25;

import {IBCoWFactory} from 'interfaces/IBCoWFactory.sol';
import {IBCoWPool} from 'interfaces/IBCoWPool.sol';

import {ICOWAMMPoolHelper} from '@cow-amm/interfaces/ICOWAMMPoolHelper.sol';
import {GetTradeableOrder} from '@cow-amm/libraries/GetTradeableOrder.sol';

import {IERC20} from '@cowprotocol/interfaces/IERC20.sol';
import {GPv2Interaction} from '@cowprotocol/libraries/GPv2Interaction.sol';
import {GPv2Order} from '@cowprotocol/libraries/GPv2Order.sol';

import {BMath} from 'contracts/BMath.sol';

/**
* @title BCoWHelper
* @notice Helper contract that allows to trade on CoW Swap Protocol.
* @dev This contract supports only 2-token equal-weights pools.
*/
contract BCoWHelper is ICOWAMMPoolHelper, BMath {
using GPv2Order for GPv2Order.Data;

/// @notice The app data used by this helper's factory.
bytes32 internal immutable _APP_DATA;

/// @inheritdoc ICOWAMMPoolHelper
// solhint-disable-next-line style-guide-casing
address public immutable factory;

constructor(address factory_) {
factory = factory_;
_APP_DATA = IBCoWFactory(factory_).APP_DATA();
}

/// @inheritdoc ICOWAMMPoolHelper
function order(
address pool,
uint256[] calldata prices
)
external
view
returns (
GPv2Order.Data memory order_,
GPv2Interaction.Data[] memory preInteractions,
GPv2Interaction.Data[] memory postInteractions,
bytes memory sig
)
{
address[] memory tokens_ = tokens(pool);

GetTradeableOrder.GetTradeableOrderParams memory params = GetTradeableOrder.GetTradeableOrderParams({
pool: pool,
token0: IERC20(tokens_[0]),
token1: IERC20(tokens_[1]),
// The price of this function is expressed as amount of
// token1 per amount of token0. The `prices` vector is
// expressed the other way around.
priceNumerator: prices[1],
priceDenominator: prices[0],
appData: _APP_DATA
});

order_ = GetTradeableOrder.getTradeableOrder(params);

{
// NOTE: Using calcOutGivenIn for the sell amount in order to avoid possible rounding
// issues that may cause invalid orders. This prevents CoW Protocol back-end from generating
// orders that may be ignored due to rounding-induced reverts.

uint256 balanceToken0 = IERC20(tokens_[0]).balanceOf(pool);
uint256 balanceToken1 = IERC20(tokens_[1]).balanceOf(pool);
(uint256 balanceIn, uint256 balanceOut) =
address(order_.buyToken) == tokens_[0] ? (balanceToken0, balanceToken1) : (balanceToken1, balanceToken0);

order_.sellAmount = calcOutGivenIn({
tokenBalanceIn: balanceIn,
tokenWeightIn: 1e18,
tokenBalanceOut: balanceOut,
tokenWeightOut: 1e18,
tokenAmountIn: order_.buyAmount,
swapFee: 0
});
}

// A ERC-1271 signature on CoW Protocol is composed of two parts: the
// signer address and the valid ERC-1271 signature data for that signer.
bytes memory eip1271sig;
eip1271sig = abi.encode(order_);
sig = abi.encodePacked(pool, eip1271sig);

// Generate the order commitment pre-interaction
bytes32 domainSeparator = IBCoWPool(pool).SOLUTION_SETTLER_DOMAIN_SEPARATOR();
bytes32 orderCommitment = order_.hash(domainSeparator);

preInteractions = new GPv2Interaction.Data[](1);
preInteractions[0] = GPv2Interaction.Data({
target: pool,
value: 0,
callData: abi.encodeWithSelector(IBCoWPool.commit.selector, orderCommitment)
});

return (order_, preInteractions, postInteractions, sig);
}

/// @inheritdoc ICOWAMMPoolHelper
function tokens(address pool) public view virtual returns (address[] memory tokens_) {
// reverts in case pool is not deployed by the helper's factory
if (!IBCoWFactory(factory).isBPool(pool)) {
revert PoolDoesNotExist();
}

// call reverts with `BPool_PoolNotFinalized()` in case pool is not finalized
tokens_ = IBCoWPool(pool).getFinalTokens();

// reverts in case pool is not supported (non-2-token pool)
if (tokens_.length != 2) {
revert PoolDoesNotExist();
}
// reverts in case pool is not supported (non-equal weights)
if (IBCoWPool(pool).getNormalizedWeight(tokens_[0]) != IBCoWPool(pool).getNormalizedWeight(tokens_[1])) {
revert PoolDoesNotExist();
}
}
}
2 changes: 1 addition & 1 deletion src/contracts/BConst.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ contract BConst {
/// @notice The minimum swap fee that can be set.
uint256 public constant MIN_FEE = BONE / 10 ** 6;
/// @notice The maximum swap fee that can be set.
uint256 public constant MAX_FEE = BONE / 10;
uint256 public constant MAX_FEE = BONE - MIN_FEE;
/// @notice The immutable exit fee percentage
uint256 public constant EXIT_FEE = 0;

Expand Down
32 changes: 8 additions & 24 deletions src/contracts/BPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,6 @@ contract BPool is BToken, BMath, IBPool {

_pullUnderlying(tokenIn, msg.sender, tokenAmountIn);
_pushUnderlying(tokenOut, msg.sender, tokenAmountOut);

return (tokenAmountOut, spotPriceAfter);
}

/// @inheritdoc IBPool
Expand Down Expand Up @@ -339,8 +337,6 @@ contract BPool is BToken, BMath, IBPool {

_pullUnderlying(tokenIn, msg.sender, tokenAmountIn);
_pushUnderlying(tokenOut, msg.sender, tokenAmountOut);

return (tokenAmountIn, spotPriceAfter);
}

/// @inheritdoc IBPool
Expand Down Expand Up @@ -370,8 +366,6 @@ contract BPool is BToken, BMath, IBPool {
_mintPoolShare(poolAmountOut);
_pushPoolShare(msg.sender, poolAmountOut);
_pullUnderlying(tokenIn, msg.sender, tokenAmountIn);

return poolAmountOut;
}

/// @inheritdoc IBPool
Expand Down Expand Up @@ -405,8 +399,6 @@ contract BPool is BToken, BMath, IBPool {
_mintPoolShare(poolAmountOut);
_pushPoolShare(msg.sender, poolAmountOut);
_pullUnderlying(tokenIn, msg.sender, tokenAmountIn);

return tokenAmountIn;
}

/// @inheritdoc IBPool
Expand Down Expand Up @@ -440,8 +432,6 @@ contract BPool is BToken, BMath, IBPool {
_burnPoolShare(bsub(poolAmountIn, exitFee));
_pushPoolShare(FACTORY, exitFee);
_pushUnderlying(tokenOut, msg.sender, tokenAmountOut);

return tokenAmountOut;
}

/// @inheritdoc IBPool
Expand Down Expand Up @@ -477,12 +467,10 @@ contract BPool is BToken, BMath, IBPool {
_burnPoolShare(bsub(poolAmountIn, exitFee));
_pushPoolShare(FACTORY, exitFee);
_pushUnderlying(tokenOut, msg.sender, tokenAmountOut);

return poolAmountIn;
}

/// @inheritdoc IBPool
function getSpotPrice(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256 spotPrice) {
function getSpotPrice(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256) {
if (!_records[tokenIn].bound) {
revert BPool_TokenNotBound();
}
Expand All @@ -492,19 +480,17 @@ contract BPool is BToken, BMath, IBPool {
Record storage inRecord = _records[tokenIn];
Record storage outRecord = _records[tokenOut];

spotPrice = calcSpotPrice(
return calcSpotPrice(
IERC20(tokenIn).balanceOf(address(this)),
inRecord.denorm,
IERC20(tokenOut).balanceOf(address(this)),
outRecord.denorm,
_swapFee
);

return spotPrice;
}

/// @inheritdoc IBPool
function getSpotPriceSansFee(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256 spotPrice) {
function getSpotPriceSansFee(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256) {
if (!_records[tokenIn].bound) {
revert BPool_TokenNotBound();
}
Expand All @@ -514,15 +500,13 @@ contract BPool is BToken, BMath, IBPool {
Record storage inRecord = _records[tokenIn];
Record storage outRecord = _records[tokenOut];

spotPrice = calcSpotPrice(
return calcSpotPrice(
IERC20(tokenIn).balanceOf(address(this)),
inRecord.denorm,
IERC20(tokenOut).balanceOf(address(this)),
outRecord.denorm,
0
);

return spotPrice;
}

/// @inheritdoc IBPool
Expand All @@ -531,8 +515,8 @@ contract BPool is BToken, BMath, IBPool {
}

/// @inheritdoc IBPool
function isBound(address t) external view returns (bool) {
return _records[t].bound;
function isBound(address token) external view returns (bool) {
return _records[token].bound;
}

/// @inheritdoc IBPool
Expand All @@ -541,12 +525,12 @@ contract BPool is BToken, BMath, IBPool {
}

/// @inheritdoc IBPool
function getCurrentTokens() external view _viewlock_ returns (address[] memory tokens) {
function getCurrentTokens() external view _viewlock_ returns (address[] memory) {
return _tokens;
}

/// @inheritdoc IBPool
function getFinalTokens() external view _viewlock_ _finalized_ returns (address[] memory tokens) {
function getFinalTokens() external view _viewlock_ _finalized_ returns (address[] memory) {
return _tokens;
}

Expand Down
4 changes: 2 additions & 2 deletions src/contracts/BToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ contract BToken is ERC20 {
*/
function increaseApproval(address spender, uint256 amount) external returns (bool success) {
_approve(msg.sender, spender, allowance(msg.sender, spender) + amount);
return true;
success = true;
}

/**
Expand All @@ -34,7 +34,7 @@ contract BToken is ERC20 {
} else {
_approve(msg.sender, spender, oldValue - amount);
}
return true;
success = true;
}

/**
Expand Down
Loading

0 comments on commit 58bd01d

Please sign in to comment.