Skip to content

Commit

Permalink
Merge pull request #240 from rainlanguage/2024-10-25-owner-limit
Browse files Browse the repository at this point in the history
owner limit
  • Loading branch information
rouzwelt authored Nov 28, 2024
2 parents d37eafb + bee81c0 commit 43bc191
Show file tree
Hide file tree
Showing 24 changed files with 1,803 additions and 621 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ cache
contracts
docs
dist
lib
10 changes: 4 additions & 6 deletions DiagOrder.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
- you need foundry installed on your machine for this process, as well as having `forge-std` lib for contract dependencies, or if you have nix package manager installed you can enter the default shell where all the deps are available.
- go to the `./diag/DiagOrder.sol` file and modify the data with the ones you want ot diag:
- add the rpc url of the evm network
- add the block number at which the debugging should take place.
- replace the `from` address with the transaction sender address, ie msg.sender.
- replace the `to` address with the arb contract address on the desired network.
- replace the `data` with the calldata without leading 0x taken from otel (hyperdx).
- save the file and now you can run the following command to get the traces:
```bash
forge script diag/DiagOrder.sol:DiagOrder -vvvvv --fork-url <url> --fork-block-number <blocknumber> --sender <addres>
forge script diag/DiagOrder.sol:DiagOrder -vvvvv
```
- replace the `path` with the location of the saved file in previous step,
- replace the `<url>` with the network rpc url,
- replace the `<blocknumber>` with the block number taken from otel spans,
- replace the `<address>` with the bot's sender address, can be taken from otel spans
- click enter and wait to get the traces

after the traces are printed, the desired data can be extraced.
here are some examples to explain the steps required to get the desired data:
Expand Down
25 changes: 15 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,18 @@ Other optional arguments are:
- `--sleep`, Seconds to wait between each arb round, default is 10, Will override the 'SLEEP' in env variables
- `--max-ratio`, Option to maximize maxIORatio, Will override the 'MAX_RATIO' in env variables
- `--timeout`, Optional seconds to wait for the transaction to mine before disregarding it, Will override the 'TIMEOUT' in env variables
- `--flashbot-rpc`, Optional flashbot rpc url to submit transaction to, Will override the 'FLASHBOT_RPC' in env variables
- `--no-bundle`, Flag for not bundling orders based on pairs and clear each order individually. Will override the 'NO_BUNDLE' in env variables
- `--write-rpc`, Option to explicitly use for write transactions, such as flashbots or mev protect rpc to protect against mev attacks, Will override the 'WRITE_RPC' in env variables
- `--hops`, Option to specify how many hops the binary search should do, default is 0 if left unspecified, Will override the 'HOPS' in env variables
- `--retries`, Option to specify how many retries should be done for the same order, max value is 3, default is 1 if left unspecified, Will override the 'RETRIES' in env variables
- `--pool-update-interval`, Option to specify time (in minutes) between pools updates, default is 15 minutes, Will override the 'POOL_UPDATE_INTERVAL' in env variables
- `--self-fund-orders`, Specifies owned order to get funded once their vault goes below the specified threshold, example: token,vaultId,threshold,toptupamount;token,vaultId,threshold,toptupamount;... . Will override the 'SELF_FUND_ORDERS' in env variables
- `--route`, Specifies the routing mode 'multi' or 'single' or 'full', default is 'single'. Will override the 'ROUTE' in env variables
- `-w` or `--wallet-count`, Number of wallet to submit transactions with, requirs `--mnemonic`. Will override the 'WALLET_COUNT' in env variables
- `-t` or `--topup-amount`, The initial topup amount of excess wallets, requirs `--mnemonic`. Will override the 'TOPUP_AMOUNT' in env variables
- `--owner-profile`, Specifies the owner limit, example: --owner-profile 0x123456=12 . Will override the 'OWNER_PROFILE' in env variables
- `--public-rpc`, Allows to use public RPCs as fallbacks, default is false. Will override the 'PUBLIC_RPC' in env variables
- `--gas-price-multiplier`, Option to multiply the gas price fetched from the rpc as percentage, default is 107, ie +7%. Will override the 'GAS_PRICE_MULTIPLIER' in env variables
- `--gas-limit-multiplier`, Option to multiply the gas limit estimation from the rpc as percentage, default is 105, ie +5%. Will override the 'GAS_LIMIT_MULTIPLIER' in env variables
- `--gas-limit-multiplier`, Option to multiply the gas limit estimation from the rpc as percentage, default is 108, ie +8%. Will override the 'GAS_LIMIT_MULTIPLIER' in env variables
- `--tx-gas`, Option to set a static gas limit for all submitting txs. Will override the 'TX_GAS' in env variables
- `-V` or `--version`, output the version number
- `-h` or `--help`, output usage information
Expand Down Expand Up @@ -161,7 +162,6 @@ Other optional arguments are:
`HyperBlast`,
`KinetixV2`,
`KinetixV3`,
`Camelot`,
`Enosys`,
`BlazeSwap`,

Expand All @@ -185,8 +185,8 @@ MNEMONIC=""
# for specifying more than 1 RPC in the env, separate them by a comma and a space
RPC_URL="https://polygon-mainnet.g.alchemy.com/v2/{API_KEY}, https://rpc.ankr.com/polygon/{API_KEY}"

# Option to submit transactions using the flashbot RPC.
FLASHBOT_RPC=""
# Option to explicitly use for write transactions, such as flashbots or mev protect rpc to protect against mev attacks.
WRITE_RPC=""

# arb contract address
ARB_ADDRESS="0x123..."
Expand Down Expand Up @@ -222,9 +222,6 @@ MAX_RATIO="true"
# Optional seconds to wait for the transaction to mine before disregarding it
TIMEOUT=""

# Flag for not bundling orders based on pairs and clear each order individually
NO_BUNDLE="false"

# number of hops of binary search, if left unspecified will be 7 by default
HOPS=11

Expand Down Expand Up @@ -253,13 +250,19 @@ BOT_MIN_BALANCE=
# example: token,vaultId,threshold,toptupamount;token,vaultId,threshold,toptupamount;...
SELF_FUND_ORDERS=

# Specifies the owner limit, in form of owner1=limit,owner2=limit,... , example: 0x123456=12,0x3456=44
OWNER_PROFILE=

# Allows to use public RPCs as fallbacks, default is false
PUBLIC_RPC=

# Specifies the routing mode 'multi' or 'single' or 'full', default is 'single'
ROUTE="single"

# Option to multiply the gas price fetched from the rpc as percentage, default is 107, ie +7%
GAS_PRICE_MULTIPLIER=

# Option to multiply the gas limit estimation from the rpc as percentage, default is 105, ie +5%
# Option to multiply the gas limit estimation from the rpc as percentage, default is 108, ie +8%
GAS_LIMIT_MULTIPLIER=

# Option to set a static gas limit for all submitting txs
Expand All @@ -268,9 +271,11 @@ TX_GAS=
If both env variables and CLI argument are set, the CLI arguments will be prioritized and override the env variables.

If you install this app as a dependency for your project you can run it by (All the above arguments apply here as well):

```bash
arb-bot <OPTIONS>
```

<br>

## Running On Github Actions
Expand Down
7 changes: 5 additions & 2 deletions diag/DiagOrder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ import {Script} from "../lib/forge-std/src/Script.sol";

contract DiagOrder is Script {
function run() external {
vm.createSelectFork(""); // rpc url
vm.rollFork(); // block number
address to = ; // put arb contract address
address from = ;
address from = ; // sender address
bytes memory data = hex""; // put calldata here without 0x

vm.startPrank(from);
bytes memory data = hex"calldata"; // put calldata here without 0x
(bool success, bytes memory result) = to.call(data);
(success, result);
}
Expand Down
15 changes: 9 additions & 6 deletions example.env
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ MNEMONIC=""
# for specifying more than 1 RPC in the env, separate them by a comma and a space
RPC_URL="https://polygon-mainnet.g.alchemy.com/v2/{API_KEY}, https://rpc.ankr.com/polygon/{API_KEY}"

# Option to submit transactions using the flashbot RPC.
FLASHBOT_RPC=""
# Option to explicitly use these rpc for write transactions, such as flashbots or mev protect rpc to protect against mev attacks.
WRITE_RPC=""

# arb contract address
ARB_ADDRESS="0x123..."
Expand Down Expand Up @@ -48,9 +48,6 @@ MAX_RATIO="true"
# Optional seconds to wait for the transaction to mine before disregarding it
TIMEOUT=""

# Flag for not bundling orders based on pairs and clear each order individually
NO_BUNDLE="false"

# number of hops of binary search, if left unspecified will be 1 by default
HOPS=11

Expand Down Expand Up @@ -79,13 +76,19 @@ BOT_MIN_BALANCE=
# example: token,vaultId,threshold,toptupamount;token,vaultId,threshold,toptupamount;...
SELF_FUND_ORDERS=

# Specifies the owner limit, in form of owner1=limit,owner2=limit,... , example: 0x123456=12,0x3456=44
OWNER_PROFILE=

# Allows to use public RPCs as fallbacks, default is false
PUBLIC_RPC=

# Specifies the routing mode 'multi' or 'single' or 'full', default is 'single'
ROUTE="single"

# Option to multiply the gas price fetched from the rpc as percentage, default is 107, ie +7%
GAS_PRICE_MULTIPLIER=

# Option to multiply the gas limit estimation from the rpc as percentage, default is 105, ie +5%
# Option to multiply the gas limit estimation from the rpc as percentage, default is 108, ie +8%
GAS_LIMIT_MULTIPLIER=

# Option to set a static gas limit for all submitting txs
Expand Down
1 change: 1 addition & 0 deletions src/abis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const ClearConfig =
*/
export const orderbookAbi = [
`event AddOrderV2(address sender, bytes32 orderHash, ${OrderV3} order)`,
`event RemoveOrderV2(address sender, bytes32 orderHash, ${OrderV3} order)`,
`event AfterClear(address sender, ${ClearStateChange} clearStateChange)`,
"function vaultBalance(address owner, address token, uint256 vaultId) external view returns (uint256 balance)",
`function deposit2(address token, uint256 vaultId, uint256 amount, ${TaskV1}[] calldata tasks) external`,
Expand Down
47 changes: 33 additions & 14 deletions src/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export async function initAccounts(
const mainAccount = await createViemClient(
config.chain.id as ChainId,
config.rpc,
undefined,
config.publicRpc,
isMnemonic
? mnemonicToAccount(mnemonicOrPrivateKey, {
addressIndex: MainAccountDerivationIndex,
Expand All @@ -59,7 +59,7 @@ export async function initAccounts(
await createViemClient(
config.chain.id as ChainId,
config.rpc,
undefined,
config.publicRpc,
mnemonicToAccount(mnemonicOrPrivateKey, {
addressIndex,
}),
Expand Down Expand Up @@ -210,7 +210,7 @@ export async function manageAccounts(
const acc = await createViemClient(
config.chain.id as ChainId,
config.rpc,
undefined,
config.publicRpc,
mnemonicToAccount(options.mnemonic!, {
addressIndex: ++lastIndex,
}),
Expand Down Expand Up @@ -337,7 +337,7 @@ export async function rotateProviders(config: BotConfig, resetDataFetcher = true
const viemClient = await createViemClient(
config.chain.id as ChainId,
config.rpc,
false,
config.publicRpc,
undefined,
config.timeout,
undefined,
Expand All @@ -348,7 +348,7 @@ export async function rotateProviders(config: BotConfig, resetDataFetcher = true
config.dataFetcher = await getDataFetcher(
viemClient as any as PublicClient,
config.lps,
false,
config.publicRpc,
);
} else {
config.dataFetcher.web3Client = viemClient as any as PublicClient;
Expand All @@ -361,7 +361,7 @@ export async function rotateProviders(config: BotConfig, resetDataFetcher = true
const mainAcc = await createViemClient(
config.chain.id as ChainId,
config.rpc,
false,
config.publicRpc,
config.mainAccount.account,
config.timeout,
undefined,
Expand All @@ -379,7 +379,7 @@ export async function rotateProviders(config: BotConfig, resetDataFetcher = true
const acc = await createViemClient(
config.chain.id as ChainId,
config.rpc,
false,
config.publicRpc,
config.accounts[i].account,
config.timeout,
undefined,
Expand All @@ -391,7 +391,11 @@ export async function rotateProviders(config: BotConfig, resetDataFetcher = true
}
} else {
if (resetDataFetcher) {
config.dataFetcher = await getDataFetcher(config.viemClient, config.lps, false);
config.dataFetcher = await getDataFetcher(
config.viemClient,
config.lps,
config.publicRpc,
);
}
}
}
Expand Down Expand Up @@ -521,11 +525,11 @@ export async function sweepToMainWallet(
balance,
]) as `0x${string}`,
};
txs.push({ tx, bounty, balance: ethers.utils.formatUnits(balance, bounty.decimals) });
const gas = await fromWallet.estimateGas(tx);
txs.push({ tx, bounty, balance: ethers.utils.formatUnits(balance, bounty.decimals) });
cumulativeGasLimit = cumulativeGasLimit.add(gas);
} catch {
failedBounties.push(bounty);
addWatchedToken(bounty, failedBounties);
}
}

Expand Down Expand Up @@ -608,7 +612,7 @@ export async function sweepToMainWallet(
code: SpanStatusCode.ERROR,
message: "Failed to sweep back to main wallet: tx reverted",
});
failedBounties.push(txs[i].bounty);
addWatchedToken(txs[i].bounty, failedBounties);
}
fromWallet.BALANCE = fromWallet.BALANCE.sub(txCost);
} catch (error) {
Expand All @@ -617,14 +621,14 @@ export async function sweepToMainWallet(
code: SpanStatusCode.ERROR,
message: "Failed to sweep back to main wallet: " + errorSnapshot("", error),
});
failedBounties.push(txs[i].bounty);
addWatchedToken(txs[i].bounty, failedBounties);
}
span?.end();
}

// empty gas if all tokens are swept
if (!failedBounties.length) {
const span = tracer?.startSpan("sweep-gas-to-main-wallet", undefined, mainCtx);
const span = tracer?.startSpan("sweep-remaining-gas-to-main-wallet", undefined, mainCtx);
span?.setAttribute("details.wallet", fromWallet.account.address);
try {
const gasLimit = ethers.BigNumber.from(
Expand Down Expand Up @@ -885,7 +889,22 @@ export async function sweepToEth(config: BotConfig, tracer?: Tracer, ctx?: Conte
}

export async function setWatchedTokens(account: ViemClient, watchedTokens: TokenDetails[]) {
account.BOUNTY = watchedTokens;
account.BOUNTY = [...watchedTokens];
}

export function addWatchedToken(
token: TokenDetails,
watchedTokens: TokenDetails[],
account?: ViemClient,
) {
if (!watchedTokens.find((v) => v.address.toLowerCase() === token.address.toLowerCase())) {
watchedTokens.push(token);
}
if (account) {
if (!account.BOUNTY.find((v) => v.address.toLowerCase() === token.address.toLowerCase())) {
account.BOUNTY.push(token);
}
}
}

/**
Expand Down
Loading

0 comments on commit 43bc191

Please sign in to comment.