Simulation
General Strategy Interfacing
Arbitrageurs are agents that need to get specific pricing info from the arbitrage target. While the mechanics of the arbitrage might be different from each other, and require different variables, there is a universal set of actions and information they require.
Arbitrageur needs:
- To get the current price of a pool that is the arbitrage target
- Depends on smart contract call to pool
- To get the reference market to fill the arbitrage with (target price)
- Depends on price path / liquid exchange smart contract call
- Get the amount out of tokens given an amount in
- Depends on smart contract call to pool
- Get the swap fee charged by the pool, since it affects the arbitrageur's incentive
- Depends on smart contract call to pool
- Compute the amount to swap and expect out, given the above information
- Depends on arbitrageur's implementation, whether root finding or algebra
- Execute the swap
- Depends on smart contract call to arbitrageur's smart contract
Arbitrageur specifically needs to compute exactly the amount of tokens to swap to reach a target price that is within its desired arb bounds.
Sim flow:
- Create environment
- Create each agent as their own structs with implementations, which deploy their respective contracts.
- Initialize/add liquidity to the target pool
- Update the block
- Push the initial prices to the weight changer entity via weight_agent.init()
- Start the event logger
- Enter the loop over the price path
- Update the price on the price path
- Take a step on the arbitrageur loop
- Update the block
- Take a step on the weight changer agent
Agents
All agents that interact with the sim have a step
that they take which runs their own logic. They also have a startup
method which should be called outside of the main simulation loop to initialize their state.
These methods can be a trait that is implemented by the agents, then the agents that implement these traits can be put into a vec that is iterated over, and that's our main sim loop.
Strategies
Both the local agents, the arbitrageur and liquidity provider, need access to the Strategy methods to interact with the strategy, whether that's computing actions to take or taking the action. For example, the arbitrageur needs to get price info from the strategy's respective contracts, while the liquidity provider needs to initialize the pool and add tokens into it.
These agents are sharing the same interface, that can be a trait implemented over the contract instance.