Understanding Smart Contracts
Subgraph is a framework to automate the process of indexing smart contract events with some extra features that are quite useful. Before jumping into the smart contracts code we need to develop an idea of what we are looking for in the smart contracts. We don't need to understand whole smart contracts, we need to understand just enough to be able to capture data for interactions discussed in previous article Understanding The Protocol.
After developing subgraphs for almost dozens of protocols our team has come up with certain steps to understand only relevant information from smart contracts. You don't need to follow these steps if you prefer but we highly recommend following these steps if you are not one of the developers of the smart contracts. It will save you time and help you avoid common mistakes while developing the subgraph.
Most of the protocols are complex decentralized application and need to be developed as a collection of smart contracts that talk to each other to achieve the desired functionality within limitations of EVM and blockchain execution context. In almost all cases there is always a core contract that implements methods to update state on user interaction. Other smart contracts are more or less implementations of user friendly external functions.
SushiSwap protocol also has one core smart contract
UniswapV2Pair.sol
. For those of you who are not aware SushiSwap is a fork of Uniswap V2. This UniswapV2Pair.sol
is the one that keeps market reserves and liquidity provider token balances.Some protocols deploy the core contract manually and some has a factory contract that deploys these core contracts. SushiSwap also has a
UniswapV2Factory.sol
which deploys UniswapV2Pair.sol.
In most of the protocols there are multiple instances of core contract are deployed, each with a different configuration which represents an individual market. In this case we say that every market has a different smart contract address. SushiSwap exchanges
UniswapV2Pair.sol
represents one market for each instance deployed.In some cases protocols one instance of the core contract is deployed and this contract itself has functions to add or remove markets by updating it's internal state variables. One example of such protocol is SushiSwap Farms.
We need to go through code of methods implementing core user interactions and find events emitted by them. Some protocols design these events carefully and include all the required data in event arguments and some don't include all the required data in these event arguments. Unfortunately protocol developers design events to fulfill their indexing needs which is mostly collecting statics on market like daily volume, total locked value. Therefore in most of the protocols these events don't have all the required data points for our subgraph.
In case we find that events don't include all the required data then we need to find ways to collect that info from method arguments or return values of the core interaction method or other methods that this core interaction method calls on other supporting smart contracts.
- 1.
Mint(address indexed sender, uint amount0, uint amount1)
- 2.
Burn(address indexed sender, uint amount0, uint amount1, address indexed to)
- 3.
Swap(address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to)
- 4.
Sync(uint112 reserve0, uint112 reserve1)
Looking at the code of
mint
, burn
and swap
methods we find that Sync
event is fired in every time there is a change in reserves of the market. Mint
and Burn
events are emitted every time a user invests in the market and redeems from the market respectively.Sync
event has required data in the arguments to call updateMarket
function of SimpleFi subgraph mapping library code but Mint
and Burn
events don't have all the required data points for calling investInMarket
and redeemFromMarket
function of library code.We see that
mint
method calls _mint
method which is implemented in UniswapV2ERC20.sol
which emits Transfer
event. Then it calls _update
method which emits Sync
event and then finally emits Mint
event. Let's look at all these events in the order they are emitted with their arguments -- 1.
Transfer(address indexed from, address indexed to, uint value)
- 2.
Sync(uint112 reserve0, uint112 reserve1)
- 3.
Mint(address indexed sender, uint amount0, uint amount1)
We can get amount of positional token minted from
Transfer
event last argument value
.The Mint
event arguments amount0
and amount1
can be used as amount of assets that are deposited by the sender
in the market. The Sync
already includes arguments to tell us about change in reserves of the market.Now question arises that there are a lot of
Transfer
events then how do we find out if a specific instance of the Transfer
event is part of this mint
call?_mint
method emits Transfer
event with from
argument as address(0)
which means we can easily recognize if a Transfer
event is part of a mint
method call or not.burn
method of UniswapV2Pair.sol
also emits following events in order -- 1.
Transfer(address indexed from, address indexed to, uint value)
- 2.
Sync(uint112 reserve0, uint112 reserve1)
- 3.
Burn(address indexed sender, uint amount0, uint amount1, address indexed to)
We can get amount of positional token minted from
Transfer
event last argument value
.The Burn
event arguments amount0
and amount1
can be used as amount of assets that are deposited by the sender
in the market. The Sync
already includes arguments to tell us about change in reserves of the market.The problem with using
Transfer
event for burn
method is that we can not be sure that every Transfer
event with to
argument as address(0)
is part of burn
method because a user or a smart contract can accidentally send their LP tokens to address(0)
but this manual send to zero address is not going to change total supply or reserves of the market. It will only increase balance of zero address. To handle this specific case we will need to use an attribute that will keep track of last transfer to zero, which may or may not be part of a burn
call.Last modified 1yr ago