Skip to content

Commit

Permalink
Merge branch 'main' into revert-quote-id-logic
Browse files Browse the repository at this point in the history
  • Loading branch information
sunce86 authored Oct 31, 2024
2 parents 3872e0c + 516b0fe commit 288138a
Show file tree
Hide file tree
Showing 7 changed files with 295 additions and 1 deletion.
90 changes: 90 additions & 0 deletions .github/workflows/playground-check.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Playground operation check

on:
pull_request:
schedule:
# Run this job once per day
- cron: "0 0 * * *"

jobs:
playground-check:
runs-on: ubuntu-latest
env:
FORK_URL_MAINNET: ${{ secrets.FORK_URL_MAINNET }}
steps:
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@main
with:
tool-cache: false
android: true
dotnet: true
haskell: true
large-packages: false
docker-images: false
swap-storage: false

- name: Checkout code
uses: actions/checkout@v4

- name: Install dependency
run: sudo apt-get -qq update && sudo apt-get -y -q install curl jq

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1

- name: Setup environment
run: |
cp playground/.env.example playground/.env
sed -i -e 's/ETH_RPC_URL=.*/ETH_RPC_URL=$FORK_URL_MAINNET/g' playground/.env
cat playground/.env
- name: Start docker containers
id: containers
run: |
cd playground
# firstly start explorer container to workaround yarn cache problem
docker compose -f docker-compose.fork.yml up -d explorer
docker compose -f docker-compose.fork.yml up -d
- name: Execute validation script
id: test_script
run: |
cd playground
./test_playground.sh
- name: Collect docker logs on failure
if: failure()
uses: jwalton/gh-docker-logs@v2
with:
dest: './logs'

- name: Tar logs
if: failure()
run: tar cvzf ./logs.tgz ./logs

- name: Upload logs to GitHub
if: failure()
id: artifact-upload-step
uses: actions/upload-artifact@v4
with:
name: logs.tgz
path: ./logs.tgz

- name: Slack notification on failure
if: failure()
id: slack
uses: slackapi/[email protected]
with:
payload: |
{
"channel_id": "C037PB929ME",
"job_link":"${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"actor":"${{ github.actor }}",
"event_name":"${{ github.event_name }}",
"head_ref":"${{ github.head_ref }}",
"step_containers":"${{ steps.containers.conclusion }}",
"step_test_script":"${{ steps.test_script.conclusion }}",
"log_artifcat":"${{ steps.artifact-upload-step.outputs.artifact-url }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_PLAYGROUND_CI_WEBHOOK_URL }}
37 changes: 37 additions & 0 deletions crates/contracts/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,43 @@ fn main() {
},
)
});
generate_contract_with_config("BalancerV2ComposableStablePoolFactoryV6", |builder| {
builder
.contract_mod_override("balancer_v2_composable_stable_pool_factory_v6")
.add_network(
MAINNET,
Network {
address: addr("0x5B42eC6D40f7B7965BE5308c70e2603c0281C1E9"),
// <https://etherscan.io/tx/0x4149cadfe5d3431205d9819fca44ed7a4c2b101adc51adc75cc4586dee237be8>
deployment_information: Some(DeploymentInformation::BlockNumber(19314764)),
},
)
.add_network(
GNOSIS,
Network {
address: addr("0x47B489bf5836f83ABD928C316F8e39bC0587B020"),
// <https://gnosisscan.io/tx/0xc3fc1fb96712a0659b7e9e5f406f63bdf5cbd5df9e04f0372c28f75785036791>
deployment_information: Some(DeploymentInformation::BlockNumber(32650879)),
},
)
.add_network(
// <https://docs.balancer.fi/reference/contracts/deployment-addresses/sepolia.html#ungrouped-active-current-contracts>
SEPOLIA,
Network {
address: addr("0x05503B3aDE04aCA81c8D6F88eCB73Ba156982D2B"),
// <https://sepolia.etherscan.io/tx/0x53aa3587002469b758e2bb87135d9599fd06e7be944fe61c7f82045c45328566>
deployment_information: Some(DeploymentInformation::BlockNumber(5369821)),
},
)
.add_network(
ARBITRUM_ONE,
Network {
address: addr("0x4bdCc2fb18AEb9e2d281b0278D946445070EAda7"),
// <https://arbiscan.io/tx/0xfa1e7642e135fb32dc14c990b851e5e7a0ac7a463e3a60c5003ae4142396f45e>
deployment_information: Some(DeploymentInformation::BlockNumber(184805448)),
},
)
});
generate_contract("BalancerV2WeightedPool");
generate_contract_with_config("BalancerV2StablePool", |builder| {
builder.add_method_alias(
Expand Down
1 change: 1 addition & 0 deletions crates/contracts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ include_contracts! {
BalancerV2ComposableStablePoolFactoryV3;
BalancerV2ComposableStablePoolFactoryV4;
BalancerV2ComposableStablePoolFactoryV5;
BalancerV2ComposableStablePoolFactoryV6;
BalancerV2LiquidityBootstrappingPool;
BalancerV2LiquidityBootstrappingPoolFactory;
BalancerV2NoProtocolFeeLiquidityBootstrappingPoolFactory;
Expand Down
1 change: 1 addition & 0 deletions crates/driver/src/infra/liquidity/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ impl BalancerV2 {
contracts::BalancerV2ComposableStablePoolFactoryV3::raw_contract(),
contracts::BalancerV2ComposableStablePoolFactoryV4::raw_contract(),
contracts::BalancerV2ComposableStablePoolFactoryV5::raw_contract(),
contracts::BalancerV2ComposableStablePoolFactoryV6::raw_contract(),
]),
pool_deny_list: Vec::new(),
graph_url: graph_url.clone(),
Expand Down
11 changes: 10 additions & 1 deletion crates/shared/src/sources/balancer_v2/pool_fetching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ use {
BalancerV2ComposableStablePoolFactoryV3,
BalancerV2ComposableStablePoolFactoryV4,
BalancerV2ComposableStablePoolFactoryV5,
BalancerV2ComposableStablePoolFactoryV6,
BalancerV2LiquidityBootstrappingPoolFactory,
BalancerV2NoProtocolFeeLiquidityBootstrappingPoolFactory,
BalancerV2StablePoolFactoryV2,
Expand Down Expand Up @@ -180,6 +181,7 @@ pub enum BalancerFactoryKind {
ComposableStableV3,
ComposableStableV4,
ComposableStableV5,
ComposableStableV6,
}

impl BalancerFactoryKind {
Expand All @@ -197,6 +199,7 @@ impl BalancerFactoryKind {
Self::ComposableStableV3,
Self::ComposableStableV4,
Self::ComposableStableV5,
Self::ComposableStableV6,
],
100 => vec![
Self::WeightedV3,
Expand All @@ -205,11 +208,13 @@ impl BalancerFactoryKind {
Self::ComposableStableV3,
Self::ComposableStableV4,
Self::ComposableStableV5,
Self::ComposableStableV6,
],
11155111 => vec![
Self::WeightedV4,
Self::ComposableStableV4,
Self::ComposableStableV5,
Self::ComposableStableV6,
Self::NoProtocolFeeLiquidityBootstrapping,
],
_ => Default::default(),
Expand Down Expand Up @@ -271,6 +276,9 @@ impl BalancerContracts {
BalancerFactoryKind::ComposableStableV5 => {
instance!(BalancerV2ComposableStablePoolFactoryV5)
}
BalancerFactoryKind::ComposableStableV6 => {
instance!(BalancerV2ComposableStablePoolFactoryV6)
}
};

factories.insert(kind, instance);
Expand Down Expand Up @@ -422,7 +430,8 @@ async fn create_aggregate_pool_fetcher(
BalancerFactoryKind::ComposableStable
| BalancerFactoryKind::ComposableStableV3
| BalancerFactoryKind::ComposableStableV4
| BalancerFactoryKind::ComposableStableV5 => {
| BalancerFactoryKind::ComposableStableV5
| BalancerFactoryKind::ComposableStableV6 => {
registry!(BalancerV2ComposableStablePoolFactory, instance)
}
};
Expand Down
155 changes: 155 additions & 0 deletions playground/test_playground.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
#!/bin/bash

# Fail on all errors
set -e
# Fail on expand of unset variables
set -u

# Setup parameters
HOST=localhost:8080
WETH_ADDRESS="0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" # WETH token
SELL_TOKEN=$WETH_ADDRESS
BUY_TOKEN="0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" # USDC token
SELL_AMOUNT="1000000000000000000" # 1 ETH
SLIPPAGE=2 # 2%
COW_SETTLMENT_CONTRACT="0x9008D19f58AAbD9eD0D60971565AA8510560ab41"
COW_VAULT_RELAYER_CONTRACT="0xC92E8bdf79f0507f65a392b0ab4667716BFE0110"
APPDATA='{"version":"1.3.0","metadata":{}}'
MAXUINT256="115792089237316195423570985008687907853269984665640564039457584007913129639935"

# Following private key is only used for testing purposes in a local environment.
# For security reasons please do not use it on a production network, most likely
# all funds sent to this account will be stolen immediately.
PRIVATE_KEY="0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6"

# Wait for 2 minutes for all services are read
echo "Waiting until all services are ready"
curl --retry 24 --retry-delay 5 --retry-all-errors --fail-with-body -s --show-error \
-H 'accept:application/json' \
http://$HOST/api/v1/token/$BUY_TOKEN/native_price > /dev/null

# Run test flow
echo "Using private key:" $PRIVATE_KEY
receiver=$(cast wallet address $PRIVATE_KEY)

# Calculate AppData hash
app_data_hash=$(cast keccak $APPDATA)

# Deposit WETH
echo "Wrapping some ETH"
docker exec playground-chain-1 cast send --private-key $PRIVATE_KEY --value 3ether $WETH_ADDRESS > /dev/null

echo "Setting WETH allowance"
docker exec playground-chain-1 cast send --private-key $PRIVATE_KEY $WETH_ADDRESS "approve(address, uint)" $COW_VAULT_RELAYER_CONTRACT $MAXUINT256 > /dev/null

echo "Request price qoute for buying USDC for WETH"
quote_response=$( curl --retry 5 --fail-with-body -s --show-error -X 'POST' \
"http://$HOST/api/v1/quote" \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"sellToken": "'$SELL_TOKEN'",
"buyToken": "'$BUY_TOKEN'",
"from": "'$receiver'",
"receiver": "'$receiver'",
"sellTokenBalance": "erc20",
"buyTokenBalance": "erc20",
"signingScheme": "eip712",
"onchainOrder": false,
"partiallyFillable": false,
"kind": "sell",
"sellAmountBeforeFee": "'$SELL_AMOUNT'"
}')

buyAmount=$(jq -r --args '.quote.buyAmount' <<< "${quote_response}")
feeAmount=$(jq -r --args '.quote.feeAmount' <<< "${quote_response}")
validTo=$(($(date +%s) + 120)) # validity time: now + 2 minutes
sellAmount=$((SELL_AMOUNT - feeAmount))

# Apply slippage
buyAmount=$((buyAmount * ( 100 - $SLIPPAGE ) / 100 )) # apply slippage

# Prepare EIP712 message
eip712_message=$(jq -r --args '
.quote|=(.appData="'$app_data_hash'") |
.quote|=(.sellAmount="'$sellAmount'") |
.quote|=(.feeAmount="0") |
.quote|=(.buyAmount="'$buyAmount'") |
.quote|=(.validTo='$validTo') |
.quote' <<< "${quote_response}")

# Prepare EIP-712 typed struct
eip712_typed_struct='{
"types": {
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" },
{ "name": "chainId", "type": "uint256" },
{ "name": "verifyingContract", "type": "address" }
],
"Order": [
{ "name": "sellToken", "type": "address" },
{ "name": "buyToken", "type": "address" },
{ "name": "receiver", "type": "address" },
{ "name": "sellAmount", "type": "uint256" },
{ "name": "buyAmount", "type": "uint256" },
{ "name": "validTo", "type": "uint32" },
{ "name": "appData", "type": "bytes32" },
{ "name": "feeAmount", "type": "uint256" },
{ "name": "kind", "type": "string" },
{ "name": "partiallyFillable", "type": "bool" },
{ "name": "sellTokenBalance", "type": "string" },
{ "name": "buyTokenBalance", "type": "string" }
]
},
"primaryType": "Order",
"domain": {
"name": "Gnosis Protocol",
"version": "v2",
"chainId": 1,
"verifyingContract": "'$COW_SETTLMENT_CONTRACT'"
},
"message": '$eip712_message'
}'

# Compact json and escape quotes
eip712_typed_struct=$(jq -r -c <<< "${eip712_typed_struct}")
eip712_typed_struct=${eip712_typed_struct//\"/\\\"}

# Sign quote_response with private key
signature=$(cast wallet sign --private-key $PRIVATE_KEY --data \""$eip712_typed_struct"\")
echo "Intent signature:" $signature

app_data=${APPDATA//\"/\\\"} # escape quotes for json field

# Update EIP712 message with additional fields required for order submit
order_proposal=$(jq -r -c --args '
.from="'$receiver'" |
.appData|="'$app_data'" |
.appDataHash="'$app_data_hash'" |
.signature="'$signature'"' <<< "${eip712_message}")

echo "Submit an order"
orderUid=$( curl --retry 5 --fail-with-body -s --show-error -X 'POST' \
"http://$HOST/api/v1/orders" \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d "${order_proposal}")
orderUid=${orderUid:1:-1} # remove quotes
echo "Order UID: $orderUid"

for i in $(seq 1 24);
do
orderStatus=$( curl --retry 5 --fail-with-body -s --show-error -X 'GET' \
"http://$HOST/api/v1/orders/$orderUid/status" \
-H 'accept: application/json' | jq -r '.type')
echo -e -n "Order status: $orderStatus \r"
if [ "$orderStatus" = "traded" ]; then
echo -e "\nSuccess"
exit 0
fi
sleep 5
done

echo -e "\nTimeout"
exit 1

0 comments on commit 288138a

Please sign in to comment.