Sdk implementation: Sfrax adapter and substream (#91)
* feat: initial setup * feat: implemented getCapabilities and getTokens * chore: adjusted getPoolIds * feat: Initial implementation of getLimits() * feat: implemented getLimits, getTokens and internal functions for amounts * feat: implemented price * feat: implemented swap function * fix and test: fixed minor issues on adapter and setup test * debugging price function * fix: debugged price function and fixed getPriceAt function * test: testOneIncreasingPriceFoundFraxV3SFrax * fix: debugging and fixing buy function * fix: fixed getPriceAt * test: testing post trade price * fix: Fixed getPriceAt * fix: Fixed getLimits * fix: Fixed prices and improved readability * fix: Fixed price and transfers in swap * feat: Finished tests * chore: Changed approve to safeIncreaseAllowance * feat: created substream for staked frax * feat: remove useless files * feat: fixed dependencies in cargo.toml * feat: rename folder * feat: updated cargo.lock * feat: changed lib.rs, added modules.rs * feat: update modules.rs with corrects addresses * feat: rename folder in ethereum-sfrax * feat: remove useless comments, change locked asset address, rename * feat: undo changes on mod.rs in ethereum-balancer * feat: rename variable * feat: update substreams/cargo.toml * feat: modify ristfmt.toml * feat: performed code formatting * feat: modify src/abi * feat: performed formatting with nightly * feat: fix addition opeation * feat: adjust code with for i, f * feat: performed fmt inside ethereum-sfrax folder * feat: performed clippy * feat: fix with clippy warning suggests * feat: undo any change in ethereum-balancer * feat: change stakedfrax_contract.rs * fix: stakedfrax_contract.rs * feat: add blank line * feat: add #[allow(clippy::all)] on ethereum-sfrax/src/abi/mod.rs * feat: update comments on pool_factories.rs * feat: update cargo.toml and substreams.yaml * feat: add tycho evm in pb folder * feat: add params to take contracts' addresses * feat: add logic to map rewards_cycle * feat: performed fmt and fix versioning * feat: remove useless functions * feat: add logic to track rewards_to_distribute * feat: passing CI * fix: substreams.yaml * feat: fixed params in manifest Co-authored-by: mrBovo <bovo.ignazio@proton.me> * feat: fixed error in map_relative_balances function * feat: passing CI checks * fix: 🐛 hex-binary address encoding + refactoring vault-> underlying map * style: 💄 fix formatting * feat: Implemented testPoolBehaviour * alignment with propeller main * Update forge-std submodule reference to include ds-test * files update to match propeller/main * creating integration_test fir sfrax * fixed FraxV3SFraxAdapter.sol import paths * updated with correct addresses FraxV3SFraxAdapter manifest.yaml * updated sfrax manifest.yaml * updated to support sdk * integration_test sfrax updated * fix: 🐛 add reward processing * chore: ♻️ minor cleanups * fix: Fixed adapter limits * fix: fix adapter and substream sdk tests * fix: Fixed CI errors * chore: fmt * chore: Removed unused line * fix: Fixed clippy warnings * chore: formatted with rustup * chore: Removed unused line * chore: post-build formatting * chore: Formatting using different toolchain vesion * chore: 💄 format * chore: 💄 format 2 * chore: Using static address for frax * feat: Added second constructor param for sfrax * fix: Fixed limits on frax sell * chore: Fixed merge conflict with sfraxeth * chore: Remove sfraxeth_contract changes * chore: Fixed EOFs * fix: Fixed fmt on stakedfrax contract --------- Co-authored-by: mp-web3 <mp.web3.t@gmail.com> Co-authored-by: gabrir99 <gabri.ruini@gmail.com> Co-authored-by: mrBovo <bovo.ignazio@proton.me> Co-authored-by: Ignazio Bovo <ignazio@jsgenesis.com> Co-authored-by: mrBovo <bovoignazio.dev@gmail.com> Co-authored-by: Mattia <mp.web3@gmail.com>
This commit is contained in:
312
evm/src/sfrax/FraxV3SFraxAdapter.sol
Normal file
312
evm/src/sfrax/FraxV3SFraxAdapter.sol
Normal file
@@ -0,0 +1,312 @@
|
|||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
pragma solidity ^0.8.13;
|
||||||
|
|
||||||
|
import {ISwapAdapter} from "../interfaces/ISwapAdapter.sol";
|
||||||
|
import {
|
||||||
|
IERC20,
|
||||||
|
ERC20
|
||||||
|
} from "../../lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
|
||||||
|
import {SafeERC20} from
|
||||||
|
"../../lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||||
|
|
||||||
|
library FixedPointMathLib {
|
||||||
|
uint256 internal constant MAX_UINT256 = 2 ** 256 - 1;
|
||||||
|
|
||||||
|
function mulDivDown(uint256 x, uint256 y, uint256 denominator)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (uint256 z)
|
||||||
|
{
|
||||||
|
/// @solidity memory-safe-assembly
|
||||||
|
assembly {
|
||||||
|
// Equivalent to require(denominator != 0 && (y == 0 || x <=
|
||||||
|
// type(uint256).max / y))
|
||||||
|
if iszero(
|
||||||
|
mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))
|
||||||
|
) { revert(0, 0) }
|
||||||
|
|
||||||
|
// Divide x * y by the denominator.
|
||||||
|
z := div(mul(x, y), denominator)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @title FraxV3SFraxAdapter
|
||||||
|
/// @dev Adapter for FraxV3 protocol, supports Frax --> sFrax and sFrax --> Frax
|
||||||
|
contract FraxV3SFraxAdapter is ISwapAdapter {
|
||||||
|
using SafeERC20 for IERC20;
|
||||||
|
using FixedPointMathLib for uint256;
|
||||||
|
|
||||||
|
uint256 constant PRECISE_UNIT = 1e18;
|
||||||
|
|
||||||
|
ISFrax immutable sFrax;
|
||||||
|
IERC20 immutable frax;
|
||||||
|
|
||||||
|
constructor(address _sFrax, address _frax) {
|
||||||
|
sFrax = ISFrax(_sFrax);
|
||||||
|
frax = IERC20(_frax);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Check if tokens in input are supported
|
||||||
|
modifier onlySupportedTokens(address sellToken, address buyToken) {
|
||||||
|
if (
|
||||||
|
(sellToken != address(frax) && sellToken != address(sFrax))
|
||||||
|
|| (buyToken != address(frax) && buyToken != address(sFrax))
|
||||||
|
|| buyToken == sellToken
|
||||||
|
) {
|
||||||
|
revert Unavailable("This adapter only supports FRAX<->SFRAX swaps");
|
||||||
|
}
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @inheritdoc ISwapAdapter
|
||||||
|
function price(
|
||||||
|
bytes32,
|
||||||
|
address sellToken,
|
||||||
|
address buyToken,
|
||||||
|
uint256[] memory _specifiedAmounts
|
||||||
|
)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
override
|
||||||
|
onlySupportedTokens(sellToken, buyToken)
|
||||||
|
returns (Fraction[] memory _prices)
|
||||||
|
{
|
||||||
|
_prices = new Fraction[](_specifiedAmounts.length);
|
||||||
|
uint256[] memory _limits = getLimits(bytes32(0), sellToken, buyToken);
|
||||||
|
|
||||||
|
for (uint256 i = 0; i < _specifiedAmounts.length; i++) {
|
||||||
|
// prevent price above sell limits as pool will revert for
|
||||||
|
// underflow/overflow on mint/redeem
|
||||||
|
_checkLimits(_limits, OrderSide.Sell, _specifiedAmounts[i]);
|
||||||
|
|
||||||
|
_prices[i] =
|
||||||
|
getPriceAt(sellToken == address(frax), _specifiedAmounts[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @inheritdoc ISwapAdapter
|
||||||
|
function swap(
|
||||||
|
bytes32,
|
||||||
|
address sellToken,
|
||||||
|
address buyToken,
|
||||||
|
OrderSide side,
|
||||||
|
uint256 specifiedAmount
|
||||||
|
)
|
||||||
|
external
|
||||||
|
override
|
||||||
|
onlySupportedTokens(sellToken, buyToken)
|
||||||
|
returns (Trade memory trade)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
specifiedAmount == 0
|
||||||
|
|| (sellToken == address(frax) && specifiedAmount < 2)
|
||||||
|
) {
|
||||||
|
return trade;
|
||||||
|
}
|
||||||
|
|
||||||
|
// prevent swap above sell limits as pool will revert for
|
||||||
|
// underflow/overflow on mint/redeem
|
||||||
|
uint256[] memory _limits = getLimits(bytes32(0), sellToken, buyToken);
|
||||||
|
_checkLimits(_limits, side, specifiedAmount);
|
||||||
|
|
||||||
|
uint256 gasBefore = gasleft();
|
||||||
|
if (side == OrderSide.Sell) {
|
||||||
|
// sell
|
||||||
|
trade.calculatedAmount = sell(sellToken, specifiedAmount);
|
||||||
|
} else {
|
||||||
|
// buy
|
||||||
|
trade.calculatedAmount = buy(sellToken, specifiedAmount);
|
||||||
|
}
|
||||||
|
trade.gasUsed = gasBefore - gasleft();
|
||||||
|
|
||||||
|
uint256 numerator = sellToken == address(frax)
|
||||||
|
? sFrax.previewDeposit(PRECISE_UNIT)
|
||||||
|
: sFrax.previewRedeem(PRECISE_UNIT);
|
||||||
|
|
||||||
|
trade.price = Fraction(numerator, PRECISE_UNIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @inheritdoc ISwapAdapter
|
||||||
|
/// @dev there is no hard capped limit
|
||||||
|
function getLimits(bytes32, address sellToken, address buyToken)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
override
|
||||||
|
onlySupportedTokens(address(sellToken), address(buyToken))
|
||||||
|
returns (uint256[] memory limits)
|
||||||
|
{
|
||||||
|
limits = new uint256[](2);
|
||||||
|
|
||||||
|
if (sellToken == address(frax)) {
|
||||||
|
// Frax --> sFrax
|
||||||
|
limits[0] = type(uint128).max;
|
||||||
|
limits[1] = type(uint128).max;
|
||||||
|
} else {
|
||||||
|
limits[1] = sFrax.storedTotalAssets();
|
||||||
|
limits[0] = sFrax.previewWithdraw(limits[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @inheritdoc ISwapAdapter
|
||||||
|
function getCapabilities(bytes32, address, address)
|
||||||
|
external
|
||||||
|
pure
|
||||||
|
override
|
||||||
|
returns (Capability[] memory capabilities)
|
||||||
|
{
|
||||||
|
capabilities = new Capability[](5);
|
||||||
|
capabilities[0] = Capability.SellOrder;
|
||||||
|
capabilities[1] = Capability.BuyOrder;
|
||||||
|
capabilities[2] = Capability.PriceFunction;
|
||||||
|
capabilities[3] = Capability.ConstantPrice;
|
||||||
|
capabilities[4] = Capability.HardLimits;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @inheritdoc ISwapAdapter
|
||||||
|
function getTokens(bytes32)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
override
|
||||||
|
returns (address[] memory tokens)
|
||||||
|
{
|
||||||
|
tokens = new address[](2);
|
||||||
|
|
||||||
|
tokens[0] = address(frax);
|
||||||
|
tokens[1] = address(sFrax);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @inheritdoc ISwapAdapter
|
||||||
|
/// @dev Since FraxV3 is a single pool that supports FRAX and SFRAX, we
|
||||||
|
/// return it directly
|
||||||
|
function getPoolIds(uint256, uint256)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
override
|
||||||
|
returns (bytes32[] memory ids)
|
||||||
|
{
|
||||||
|
ids = new bytes32[](1);
|
||||||
|
ids[0] = bytes32(bytes20(address(sFrax)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @notice Executes a sell order on the contract.
|
||||||
|
/// @param sellToken The token being sold.
|
||||||
|
/// @param amount The amount to be traded.
|
||||||
|
/// @return calculatedAmount The amount of tokens received.
|
||||||
|
function sell(address sellToken, uint256 amount)
|
||||||
|
internal
|
||||||
|
returns (uint256 calculatedAmount)
|
||||||
|
{
|
||||||
|
IERC20(sellToken).safeTransferFrom(msg.sender, address(this), amount);
|
||||||
|
if (sellToken == address(sFrax)) {
|
||||||
|
return sFrax.redeem(amount, msg.sender, address(this));
|
||||||
|
} else {
|
||||||
|
IERC20(sellToken).safeIncreaseAllowance(address(sFrax), amount);
|
||||||
|
return sFrax.deposit(amount, msg.sender);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @notice Executes a buy order on the contract.
|
||||||
|
/// @param sellToken The token being sold.
|
||||||
|
/// @param amount The amount of buyToken to receive.
|
||||||
|
/// @return calculatedAmount The amount of tokens received.
|
||||||
|
function buy(address sellToken, uint256 amount)
|
||||||
|
internal
|
||||||
|
returns (uint256 calculatedAmount)
|
||||||
|
{
|
||||||
|
if (sellToken == address(sFrax)) {
|
||||||
|
uint256 amountIn = sFrax.previewWithdraw(amount);
|
||||||
|
IERC20(sellToken).safeTransferFrom(
|
||||||
|
msg.sender, address(this), amountIn
|
||||||
|
);
|
||||||
|
return sFrax.withdraw(amount, msg.sender, address(this));
|
||||||
|
} else {
|
||||||
|
uint256 amountIn = sFrax.previewMint(amount);
|
||||||
|
IERC20(sellToken).safeTransferFrom(
|
||||||
|
msg.sender, address(this), amountIn
|
||||||
|
);
|
||||||
|
IERC20(sellToken).safeIncreaseAllowance(address(sFrax), amountIn);
|
||||||
|
return sFrax.mint(amount, msg.sender);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @notice Calculates prices for a specified amount
|
||||||
|
/// @param isSellFrax True if selling frax, false if selling sFrax
|
||||||
|
/// @param amountIn The amount of the token being sold.
|
||||||
|
/// @return (fraction) price as a fraction corresponding to the provided
|
||||||
|
/// amount.
|
||||||
|
function getPriceAt(bool isSellFrax, uint256 amountIn)
|
||||||
|
internal
|
||||||
|
view
|
||||||
|
returns (Fraction memory)
|
||||||
|
{
|
||||||
|
if (isSellFrax == true) {
|
||||||
|
if (amountIn < 2) {
|
||||||
|
revert("Amount In must be greater than 1");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Fraction(sFrax.previewDeposit(amountIn), amountIn);
|
||||||
|
} else {
|
||||||
|
return Fraction(sFrax.previewRedeem(amountIn), amountIn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @notice Checks if the specified amount is within the hard limits
|
||||||
|
/// @dev If not, reverts
|
||||||
|
/// @param limits The limits of the tokens being traded.
|
||||||
|
/// @param side The side of the trade.
|
||||||
|
/// @param specifiedAmount The amount to be traded.
|
||||||
|
function _checkLimits(
|
||||||
|
uint256[] memory limits,
|
||||||
|
OrderSide side,
|
||||||
|
uint256 specifiedAmount
|
||||||
|
) internal pure {
|
||||||
|
if (side == OrderSide.Sell && specifiedAmount > limits[0]) {
|
||||||
|
require(specifiedAmount < limits[0], "Limit exceeded");
|
||||||
|
} else if (side == OrderSide.Buy && specifiedAmount > limits[1]) {
|
||||||
|
require(specifiedAmount < limits[1], "Limit exceeded");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ISFrax {
|
||||||
|
function previewDeposit(uint256 assets) external view returns (uint256);
|
||||||
|
|
||||||
|
function previewMint(uint256 shares) external view returns (uint256);
|
||||||
|
|
||||||
|
function previewRedeem(uint256 shares) external view returns (uint256);
|
||||||
|
|
||||||
|
function previewWithdraw(uint256 assets) external view returns (uint256);
|
||||||
|
|
||||||
|
function previewDistributeRewards()
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (uint256 _rewardToDistribute);
|
||||||
|
|
||||||
|
function pricePerShare() external view returns (uint256);
|
||||||
|
|
||||||
|
function asset() external view returns (ERC20); // FRAX
|
||||||
|
|
||||||
|
function totalSupply() external view returns (uint256);
|
||||||
|
|
||||||
|
function totalAssets() external view returns (uint256);
|
||||||
|
|
||||||
|
function deposit(uint256 assets, address receiver)
|
||||||
|
external
|
||||||
|
returns (uint256 shares);
|
||||||
|
|
||||||
|
function mint(uint256 shares, address receiver)
|
||||||
|
external
|
||||||
|
returns (uint256 assets);
|
||||||
|
|
||||||
|
function storedTotalAssets() external view returns (uint256);
|
||||||
|
|
||||||
|
function withdraw(uint256 assets, address receiver, address owner)
|
||||||
|
external
|
||||||
|
returns (uint256 shares);
|
||||||
|
|
||||||
|
function redeem(uint256 shares, address receiver, address owner)
|
||||||
|
external
|
||||||
|
returns (uint256 assets);
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@ constants:
|
|||||||
- PriceFunction
|
- PriceFunction
|
||||||
|
|
||||||
# The file containing the adapter contract
|
# The file containing the adapter contract
|
||||||
contract: IntegralSwapAdapter.sol
|
contract: FraxV3SFraxAdapter.sol
|
||||||
|
|
||||||
# Deployment instances used to generate chain specific bytecode.
|
# Deployment instances used to generate chain specific bytecode.
|
||||||
instances:
|
instances:
|
||||||
@@ -21,16 +21,17 @@ instances:
|
|||||||
name: mainnet
|
name: mainnet
|
||||||
id: 0
|
id: 0
|
||||||
arguments:
|
arguments:
|
||||||
- "0xd17b3c9784510E33cD5B87b490E79253BcD81e2E"
|
- "0xA663B02CF0a4b149d2aD41910CB81e23e1c41c32"
|
||||||
|
- "0x853d955aCEf822Db058eb8505911ED77F175b99e"
|
||||||
|
|
||||||
# Specify some automatic test cases in case getPoolIds and
|
# Specify some automatic test cases in case getPoolIds and
|
||||||
# getTokens are not implemented.
|
# getTokens are not implemented.
|
||||||
tests:
|
tests:
|
||||||
instances:
|
instances:
|
||||||
- pool_id: "0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc"
|
- pool_id: "0xA663B02CF0a4b149d2aD41910CB81e23e1c41c32" # sFrax Vault
|
||||||
sell_token: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
|
sell_token: "0x853d955aCEf822Db058eb8505911ED77F175b99e" # Frax
|
||||||
buy_token: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
|
buy_token: "0xA663B02CF0a4b149d2aD41910CB81e23e1c41c32" # sFrax
|
||||||
block: 17000000
|
block: 19270612
|
||||||
chain:
|
chain:
|
||||||
id: 0
|
id: 0
|
||||||
name: mainnet
|
name: mainnet
|
||||||
246
evm/test/FraxV3SFraxAdapter.t.sol
Normal file
246
evm/test/FraxV3SFraxAdapter.t.sol
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
pragma solidity ^0.8.13;
|
||||||
|
|
||||||
|
import "./AdapterTest.sol";
|
||||||
|
import "forge-std/Test.sol";
|
||||||
|
import "src/interfaces/ISwapAdapterTypes.sol";
|
||||||
|
import "src/libraries/FractionMath.sol";
|
||||||
|
import "src/libraries/FractionMath.sol";
|
||||||
|
import "src/sfrax/FraxV3SFraxAdapter.sol";
|
||||||
|
|
||||||
|
/// @title TemplateSwapAdapterTest
|
||||||
|
/// @dev This is a template for a swap adapter test.
|
||||||
|
/// Test all functions that are implemented in your swap adapter, the two test
|
||||||
|
/// included here are just an example.
|
||||||
|
/// Feel free to use UniswapV2SwapAdapterTest and BalancerV2SwapAdapterTest as a
|
||||||
|
/// reference.
|
||||||
|
contract FraxV3SFraxAdapterTest is Test, ISwapAdapterTypes, AdapterTest {
|
||||||
|
using FractionMath for Fraction;
|
||||||
|
|
||||||
|
FraxV3SFraxAdapter adapter;
|
||||||
|
ISFrax constant SFRAX = ISFrax(0xA663B02CF0a4b149d2aD41910CB81e23e1c41c32);
|
||||||
|
IERC20 constant FRAX = IERC20(0x853d955aCEf822Db058eb8505911ED77F175b99e);
|
||||||
|
address constant FRAX_ADDRESS = address(FRAX);
|
||||||
|
address constant SFRAX_ADDRESS = address(SFRAX);
|
||||||
|
|
||||||
|
uint256 constant TEST_ITERATIONS = 100;
|
||||||
|
uint256 constant AMOUNT0 = 1000000000000000000;
|
||||||
|
|
||||||
|
function setUp() public {
|
||||||
|
uint256 forkBlock = 19270612;
|
||||||
|
vm.createSelectFork(vm.rpcUrl("mainnet"), forkBlock);
|
||||||
|
|
||||||
|
adapter = new FraxV3SFraxAdapter(SFRAX_ADDRESS, FRAX_ADDRESS);
|
||||||
|
vm.label(address(FRAX), "FRAX");
|
||||||
|
vm.label(address(SFRAX), "SFRAX");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev set lower limit to greater than 1, because previewDeposit returns 0
|
||||||
|
/// with an amountIn == 1
|
||||||
|
function testPriceFuzzFraxV3SFrax(uint256 amount0, uint256 amount1)
|
||||||
|
public
|
||||||
|
{
|
||||||
|
uint256[] memory limits =
|
||||||
|
adapter.getLimits(bytes32(0), FRAX_ADDRESS, SFRAX_ADDRESS);
|
||||||
|
vm.assume(amount0 < limits[0]);
|
||||||
|
vm.assume(amount0 > 1);
|
||||||
|
vm.assume(amount1 < limits[0]);
|
||||||
|
vm.assume(amount1 > 1);
|
||||||
|
|
||||||
|
uint256[] memory amounts = new uint256[](2);
|
||||||
|
amounts[0] = amount0;
|
||||||
|
amounts[1] = amount1;
|
||||||
|
|
||||||
|
Fraction[] memory prices =
|
||||||
|
adapter.price(bytes32(0), FRAX_ADDRESS, SFRAX_ADDRESS, amounts);
|
||||||
|
|
||||||
|
for (uint256 i = 0; i < prices.length; i++) {
|
||||||
|
assertGt(prices[i].numerator, 0);
|
||||||
|
assertGt(prices[i].denominator, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSwapFuzzFraxV3WithFrax(uint256 specifiedAmount, bool isBuy)
|
||||||
|
public
|
||||||
|
{
|
||||||
|
OrderSide side = isBuy ? OrderSide.Buy : OrderSide.Sell;
|
||||||
|
|
||||||
|
bytes32 pair = bytes32(0);
|
||||||
|
uint256[] memory limits =
|
||||||
|
adapter.getLimits(pair, FRAX_ADDRESS, SFRAX_ADDRESS);
|
||||||
|
|
||||||
|
if (side == OrderSide.Buy) {
|
||||||
|
vm.assume(specifiedAmount < limits[1]);
|
||||||
|
|
||||||
|
deal(address(FRAX), address(this), type(uint256).max);
|
||||||
|
FRAX.approve(address(adapter), type(uint256).max);
|
||||||
|
} else {
|
||||||
|
vm.assume(specifiedAmount < limits[0]);
|
||||||
|
|
||||||
|
deal(address(FRAX), address(this), specifiedAmount);
|
||||||
|
FRAX.approve(address(adapter), specifiedAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint256 frax_balance = FRAX.balanceOf(address(this));
|
||||||
|
uint256 sfrax_balance = IERC20(SFRAX_ADDRESS).balanceOf(address(this));
|
||||||
|
|
||||||
|
ISFrax(SFRAX_ADDRESS).totalAssets();
|
||||||
|
|
||||||
|
Trade memory trade = adapter.swap(
|
||||||
|
pair, FRAX_ADDRESS, SFRAX_ADDRESS, side, specifiedAmount
|
||||||
|
);
|
||||||
|
|
||||||
|
if (trade.calculatedAmount > 0) {
|
||||||
|
if (side == OrderSide.Buy) {
|
||||||
|
assertEq(
|
||||||
|
specifiedAmount,
|
||||||
|
IERC20(SFRAX_ADDRESS).balanceOf(address(this))
|
||||||
|
- sfrax_balance
|
||||||
|
);
|
||||||
|
assertEq(
|
||||||
|
trade.calculatedAmount,
|
||||||
|
frax_balance - FRAX.balanceOf(address(this))
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
assertEq(
|
||||||
|
specifiedAmount,
|
||||||
|
frax_balance - FRAX.balanceOf(address(this))
|
||||||
|
);
|
||||||
|
assertEq(
|
||||||
|
trade.calculatedAmount,
|
||||||
|
IERC20(SFRAX_ADDRESS).balanceOf(address(this))
|
||||||
|
- sfrax_balance
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSwapFuzzFraxV3WithSFrax(uint256 specifiedAmount, bool isBuy)
|
||||||
|
public
|
||||||
|
{
|
||||||
|
OrderSide side = isBuy ? OrderSide.Buy : OrderSide.Sell;
|
||||||
|
|
||||||
|
bytes32 pair = bytes32(0);
|
||||||
|
uint256[] memory limits =
|
||||||
|
adapter.getLimits(pair, SFRAX_ADDRESS, FRAX_ADDRESS);
|
||||||
|
|
||||||
|
if (side == OrderSide.Buy) {
|
||||||
|
vm.assume(specifiedAmount < limits[1]);
|
||||||
|
|
||||||
|
deal(SFRAX_ADDRESS, address(this), type(uint256).max);
|
||||||
|
IERC20(SFRAX_ADDRESS).approve(address(adapter), type(uint256).max);
|
||||||
|
} else {
|
||||||
|
vm.assume(specifiedAmount < limits[0]);
|
||||||
|
|
||||||
|
deal(address(SFRAX_ADDRESS), address(this), specifiedAmount);
|
||||||
|
IERC20(SFRAX_ADDRESS).approve(address(adapter), specifiedAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint256 sfrax_balance = IERC20(SFRAX_ADDRESS).balanceOf(address(this));
|
||||||
|
uint256 frax_balance = FRAX.balanceOf(address(this));
|
||||||
|
|
||||||
|
Trade memory trade = adapter.swap(
|
||||||
|
pair, SFRAX_ADDRESS, FRAX_ADDRESS, side, specifiedAmount
|
||||||
|
);
|
||||||
|
|
||||||
|
if (trade.calculatedAmount > 0) {
|
||||||
|
if (side == OrderSide.Buy) {
|
||||||
|
assertEq(
|
||||||
|
specifiedAmount,
|
||||||
|
FRAX.balanceOf(address(this)) - frax_balance
|
||||||
|
);
|
||||||
|
assertEq(
|
||||||
|
trade.calculatedAmount,
|
||||||
|
sfrax_balance
|
||||||
|
- IERC20(SFRAX_ADDRESS).balanceOf(address(this))
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
assertEq(
|
||||||
|
specifiedAmount,
|
||||||
|
sfrax_balance
|
||||||
|
- IERC20(SFRAX_ADDRESS).balanceOf(address(this))
|
||||||
|
);
|
||||||
|
assertEq(
|
||||||
|
trade.calculatedAmount,
|
||||||
|
FRAX.balanceOf(address(this)) - frax_balance
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSwapSellIncreasingFraxV3() public {
|
||||||
|
executeIncreasingSwapsFraxV3(OrderSide.Sell, true);
|
||||||
|
executeIncreasingSwapsFraxV3(OrderSide.Sell, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSwapBuyIncreasingFraxV3() public {
|
||||||
|
executeIncreasingSwapsFraxV3(OrderSide.Buy, true);
|
||||||
|
executeIncreasingSwapsFraxV3(OrderSide.Buy, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function executeIncreasingSwapsFraxV3(OrderSide side, bool isFrax)
|
||||||
|
internal
|
||||||
|
{
|
||||||
|
bytes32 pair = bytes32(0);
|
||||||
|
|
||||||
|
uint256[] memory amounts = new uint256[](TEST_ITERATIONS);
|
||||||
|
for (uint256 i = 0; i < TEST_ITERATIONS; i++) {
|
||||||
|
amounts[i] = 1000 * (i + 1) * 10 ** 18;
|
||||||
|
}
|
||||||
|
|
||||||
|
Trade[] memory trades = new Trade[](TEST_ITERATIONS);
|
||||||
|
uint256 beforeSwap;
|
||||||
|
for (uint256 i = 0; i < TEST_ITERATIONS; i++) {
|
||||||
|
beforeSwap = vm.snapshot();
|
||||||
|
|
||||||
|
if (isFrax) {
|
||||||
|
deal(FRAX_ADDRESS, address(this), type(uint256).max);
|
||||||
|
FRAX.approve(address(adapter), type(uint256).max);
|
||||||
|
trades[i] = adapter.swap(
|
||||||
|
pair, FRAX_ADDRESS, SFRAX_ADDRESS, side, amounts[i]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
deal(SFRAX_ADDRESS, address(this), amounts[i]);
|
||||||
|
IERC20(SFRAX_ADDRESS).approve(address(adapter), amounts[i]);
|
||||||
|
trades[i] = adapter.swap(
|
||||||
|
pair, SFRAX_ADDRESS, FRAX_ADDRESS, side, amounts[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
vm.revertTo(beforeSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint256 i = 1; i < TEST_ITERATIONS - 1; i++) {
|
||||||
|
assertLe(trades[i].calculatedAmount, trades[i + 1].calculatedAmount);
|
||||||
|
assertLe(trades[i].gasUsed, trades[i + 1].gasUsed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetLimitsFraxV3() public {
|
||||||
|
uint256[] memory limits =
|
||||||
|
adapter.getLimits(bytes32(0), FRAX_ADDRESS, SFRAX_ADDRESS);
|
||||||
|
assertEq(limits.length, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetTokensFraxV3() public {
|
||||||
|
address[] memory tokens = adapter.getTokens(bytes32(0));
|
||||||
|
|
||||||
|
assertEq(tokens[0], FRAX_ADDRESS);
|
||||||
|
assertEq(tokens[1], SFRAX_ADDRESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetCapabilitiesFraxV3SFrax() public {
|
||||||
|
Capability[] memory res =
|
||||||
|
adapter.getCapabilities(bytes32(0), FRAX_ADDRESS, SFRAX_ADDRESS);
|
||||||
|
|
||||||
|
assertEq(res.length, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test is currently broken due to a bug in runPoolBehaviour
|
||||||
|
// with constant price pools.
|
||||||
|
// function testPoolBehaviourFraxV3Sfrax() public {
|
||||||
|
// bytes32[] memory poolIds = new bytes32[](1);
|
||||||
|
// poolIds[0] = bytes32(0);
|
||||||
|
// runPoolBehaviourTest(adapter, poolIds);
|
||||||
|
// }
|
||||||
|
}
|
||||||
44
substreams/Cargo.lock
generated
44
substreams/Cargo.lock
generated
@@ -233,7 +233,7 @@ dependencies = [
|
|||||||
"itertools 0.12.1",
|
"itertools 0.12.1",
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"prost 0.11.9",
|
"prost 0.11.9",
|
||||||
"prost-types 0.12.3",
|
"prost-types 0.12.6",
|
||||||
"substreams",
|
"substreams",
|
||||||
"substreams-ethereum",
|
"substreams-ethereum",
|
||||||
"tycho-substreams",
|
"tycho-substreams",
|
||||||
@@ -252,7 +252,7 @@ dependencies = [
|
|||||||
"itertools 0.13.0",
|
"itertools 0.13.0",
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"prost 0.11.9",
|
"prost 0.11.9",
|
||||||
"prost-types 0.12.3",
|
"prost-types 0.12.6",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_qs",
|
"serde_qs",
|
||||||
"substreams",
|
"substreams",
|
||||||
@@ -260,6 +260,26 @@ dependencies = [
|
|||||||
"tycho-substreams",
|
"tycho-substreams",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ethereum-sfrax"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"ethabi 17.2.0",
|
||||||
|
"getrandom",
|
||||||
|
"hex",
|
||||||
|
"hex-literal 0.4.1",
|
||||||
|
"itertools 0.12.1",
|
||||||
|
"num-bigint",
|
||||||
|
"num-traits",
|
||||||
|
"prost 0.11.9",
|
||||||
|
"prost-types 0.11.9",
|
||||||
|
"regex",
|
||||||
|
"substreams",
|
||||||
|
"substreams-ethereum",
|
||||||
|
"tycho-substreams",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethereum-sfraxeth"
|
name = "ethereum-sfraxeth"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -723,12 +743,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prost"
|
name = "prost"
|
||||||
version = "0.12.3"
|
version = "0.12.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a"
|
checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"prost-derive 0.12.3",
|
"prost-derive 0.12.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -768,12 +788,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prost-derive"
|
name = "prost-derive"
|
||||||
version = "0.12.3"
|
version = "0.12.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e"
|
checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"itertools 0.10.5",
|
"itertools 0.12.1",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.52",
|
"syn 2.0.52",
|
||||||
@@ -790,11 +810,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prost-types"
|
name = "prost-types"
|
||||||
version = "0.12.3"
|
version = "0.12.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e"
|
checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"prost 0.12.3",
|
"prost 0.12.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1111,7 +1131,7 @@ dependencies = [
|
|||||||
"num-bigint",
|
"num-bigint",
|
||||||
"pad",
|
"pad",
|
||||||
"prost 0.11.9",
|
"prost 0.11.9",
|
||||||
"prost-types 0.12.3",
|
"prost-types 0.12.6",
|
||||||
"substreams",
|
"substreams",
|
||||||
"substreams-entity-change",
|
"substreams-entity-change",
|
||||||
"substreams-ethereum",
|
"substreams-ethereum",
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ members = [
|
|||||||
"ethereum-ambient",
|
"ethereum-ambient",
|
||||||
"ethereum-uniswap-v2",
|
"ethereum-uniswap-v2",
|
||||||
"ethereum-uniswap-v3",
|
"ethereum-uniswap-v3",
|
||||||
"ethereum-sfraxeth",
|
"ethereum-sfrax",
|
||||||
|
"ethereum-sfraxeth"
|
||||||
]
|
]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
|
|||||||
@@ -34,18 +34,17 @@ fn get_token_registered(
|
|||||||
.clone()
|
.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is the main function that handles the creation of `ProtocolComponent`s with `Attribute`s
|
// This is the main function that handles the creation of `ProtocolComponent`s with `Attribute`s
|
||||||
/// based on the specific factory address. There's 3 factory groups that are represented here:
|
// based on the specific factory address. There's 3 factory groups that are represented here:
|
||||||
/// - Weighted Pool Factories
|
// - Weighted Pool Factories
|
||||||
/// - Linear Pool Factories
|
// - Linear Pool Factories
|
||||||
/// - Stable Pool Factories
|
// - Stable Pool Factories
|
||||||
///
|
// (Balancer does have a bit more (esp. in the deprecated section) that could be implemented as
|
||||||
/// (Balancer does have a bit more (esp. in the deprecated section) that could be implemented as
|
// desired.)
|
||||||
/// desired.)
|
// We use the specific ABIs to decode both the log event and corresponding call to gather
|
||||||
/// We use the specific ABIs to decode both the log event and corresponding call to gather
|
// `PoolCreated` event information alongside the `Create` call data that provide us details to
|
||||||
/// `PoolCreated` event information alongside the `Create` call data that provide us details to
|
// fulfill both the required details + any extra `Attributes`
|
||||||
/// fulfill both the required details + any extra `Attributes`
|
// Ref: https://docs.balancer.fi/reference/contracts/deployment-addresses/mainnet.html
|
||||||
/// Ref: https://docs.balancer.fi/reference/contracts/deployment-addresses/mainnet.html
|
|
||||||
pub fn address_map(
|
pub fn address_map(
|
||||||
pool_factory_address: &[u8],
|
pool_factory_address: &[u8],
|
||||||
log: &Log,
|
log: &Log,
|
||||||
|
|||||||
1108
substreams/ethereum-sfrax/Cargo.lock
generated
Normal file
1108
substreams/ethereum-sfrax/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
31
substreams/ethereum-sfrax/Cargo.toml
Normal file
31
substreams/ethereum-sfrax/Cargo.toml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
[package]
|
||||||
|
name = "ethereum-sfrax"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "ethereum_sfrax"
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
ethabi = "17"
|
||||||
|
hex-literal.workspace = true
|
||||||
|
num-bigint = "0.4"
|
||||||
|
num-traits = "0.2.15"
|
||||||
|
prost.workspace = true
|
||||||
|
prost-types = "0.11"
|
||||||
|
substreams.workspace = true
|
||||||
|
substreams-ethereum.workspace = true
|
||||||
|
hex.workspace = true
|
||||||
|
tycho-substreams.workspace = true
|
||||||
|
itertools = "0.12.0"
|
||||||
|
anyhow = "1.0.75"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
anyhow = "1"
|
||||||
|
substreams-ethereum = "0.9"
|
||||||
|
regex = "1.10.4"
|
||||||
|
|
||||||
|
# Required so that ethabi > ethereum-types build correctly under wasm32-unknown-unknown
|
||||||
|
[target.wasm32-unknown-unknown.dependencies]
|
||||||
|
getrandom = { version = "0.2", features = ["custom"] }
|
||||||
26
substreams/ethereum-sfrax/Makefile
Normal file
26
substreams/ethereum-sfrax/Makefile
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
CARGO_VERSION := $(shell cargo version 2>/dev/null)
|
||||||
|
|
||||||
|
.PHONY: build
|
||||||
|
build:
|
||||||
|
ifdef CARGO_VERSION
|
||||||
|
cargo build --target wasm32-unknown-unknown --release
|
||||||
|
else
|
||||||
|
@echo "Building substreams target using Docker. To speed up this step, install a Rust development environment."
|
||||||
|
docker run --rm -ti --init -v ${PWD}:/usr/src --workdir /usr/src/ rust:bullseye cargo build --target wasm32-unknown-unknown --release
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: run
|
||||||
|
run: build
|
||||||
|
substreams run substreams.yaml $(if $(MODULE),$(MODULE),map_events) $(if $(START_BLOCK),-s $(START_BLOCK)) $(if $(STOP_BLOCK),-t $(STOP_BLOCK))
|
||||||
|
|
||||||
|
.PHONY: gui
|
||||||
|
gui: build
|
||||||
|
substreams gui substreams.yaml $(if $(MODULE),$(MODULE),map_events) $(if $(START_BLOCK),-s $(START_BLOCK)) $(if $(STOP_BLOCK),-t $(STOP_BLOCK))
|
||||||
|
|
||||||
|
.PHONY: protogen
|
||||||
|
protogen:
|
||||||
|
substreams protogen ./substreams.yaml --exclude-paths="sf/substreams,google"
|
||||||
|
|
||||||
|
.PHONY: pack
|
||||||
|
pack: build
|
||||||
|
substreams pack substreams.yaml
|
||||||
File diff suppressed because one or more lines are too long
12
substreams/ethereum-sfrax/buf.gen.yaml
Normal file
12
substreams/ethereum-sfrax/buf.gen.yaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
version: v1
|
||||||
|
plugins:
|
||||||
|
- plugin: buf.build/community/neoeinstein-prost:v0.2.2
|
||||||
|
out: src/pb
|
||||||
|
opt:
|
||||||
|
- file_descriptor_set=false
|
||||||
|
|
||||||
|
- plugin: buf.build/community/neoeinstein-prost-crate:v0.3.1
|
||||||
|
out: src/pb
|
||||||
|
opt:
|
||||||
|
- no_features
|
||||||
24
substreams/ethereum-sfrax/build.rs
Normal file
24
substreams/ethereum-sfrax/build.rs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#![allow(clippy::all)]
|
||||||
|
use anyhow::{Ok, Result};
|
||||||
|
use regex::Regex;
|
||||||
|
use std::fs;
|
||||||
|
use substreams_ethereum::Abigen;
|
||||||
|
|
||||||
|
fn main() -> Result<(), anyhow::Error> {
|
||||||
|
let file_names = ["abi/stakedfrax_contract.abi.json"];
|
||||||
|
let file_output_names = ["src/abi/stakedfrax_contract.rs"];
|
||||||
|
|
||||||
|
for (i, f) in file_names.into_iter().enumerate() {
|
||||||
|
let contents = fs::read_to_string(f).expect("Should have been able to read the file");
|
||||||
|
|
||||||
|
// sanitize fields and attributes starting with an underscore
|
||||||
|
let regex = Regex::new(r#"("\w+"\s?:\s?")_(\w+")"#).unwrap();
|
||||||
|
let sanitized_abi_file = regex.replace_all(contents.as_str(), "${1}u_${2}");
|
||||||
|
|
||||||
|
Abigen::from_bytes("Contract", sanitized_abi_file.as_bytes())?
|
||||||
|
.generate()?
|
||||||
|
.write_to_file(file_output_names[i])?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
31
substreams/ethereum-sfrax/integration_test.tycho.yaml
Normal file
31
substreams/ethereum-sfrax/integration_test.tycho.yaml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Name of the substreams config file in your substreams module. Usually "./substreams.yaml"
|
||||||
|
substreams_yaml_path: ./substreams.yaml
|
||||||
|
# Name of the adapter contract, usually: ProtocolSwapAdapter
|
||||||
|
adapter_contract: "FraxV3SFraxAdapter"
|
||||||
|
# Constructor signature of the Adapter contract
|
||||||
|
adapter_build_signature: "constructor(address)"
|
||||||
|
# A comma separated list of args to be passed to the constructor of the Adapter contract
|
||||||
|
adapter_build_args: "0xA663B02CF0a4b149d2aD41910CB81e23e1c41c32,0x853d955aCEf822Db058eb8505911ED77F175b99e"
|
||||||
|
# Whether or not the testing script should skip checking balances of the protocol components.
|
||||||
|
# If set to `true` please always add a reason why it's skipped.
|
||||||
|
skip_balance_check: true
|
||||||
|
|
||||||
|
# A list of protocol types names created by your Substreams module.
|
||||||
|
protocol_type_names:
|
||||||
|
- "sfrax_vault"
|
||||||
|
|
||||||
|
# A list of tests.
|
||||||
|
tests:
|
||||||
|
# Test to validate the creation of the sFrax vault
|
||||||
|
- name: test_sfrax_vault_creation
|
||||||
|
# Indexed block range where the vault was created
|
||||||
|
start_block: 18378085
|
||||||
|
stop_block: 18380714 #2629 blocks difference 18380714
|
||||||
|
# Same as global `initialized_accounts` but only scoped to this test.
|
||||||
|
expected_components:
|
||||||
|
- id: "0xA663B02CF0a4b149d2aD41910CB81e23e1c41c32" # sFrax Vault
|
||||||
|
tokens:
|
||||||
|
- "0x853d955aCEf822Db058eb8505911ED77F175b99e" # FRAX
|
||||||
|
- "0xA663B02CF0a4b149d2aD41910CB81e23e1c41c32" # sFrax
|
||||||
|
creation_tx: "0xecd4ab27bc3b4c300b11405fc6a156ee316ad3f4c24f63130cbcbc49ae6bef55"
|
||||||
|
skip_simulation: false
|
||||||
276
substreams/ethereum-sfrax/proto/contract.proto
Normal file
276
substreams/ethereum-sfrax/proto/contract.proto
Normal file
@@ -0,0 +1,276 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
package contract.v1;
|
||||||
|
|
||||||
|
message Events {
|
||||||
|
repeated stakedfrax_Approval stakedfrax_approvals = 1;
|
||||||
|
repeated stakedfrax_Deposit stakedfrax_deposits = 2;
|
||||||
|
repeated stakedfrax_DistributeRewards stakedfrax_distribute_rewards = 3;
|
||||||
|
repeated stakedfrax_SetMaxDistributionPerSecondPerAsset stakedfrax_set_max_distribution_per_second_per_assets = 4;
|
||||||
|
repeated stakedfrax_SyncRewards stakedfrax_sync_rewards = 5;
|
||||||
|
repeated stakedfrax_TimelockTransferStarted stakedfrax_timelock_transfer_starteds = 6;
|
||||||
|
repeated stakedfrax_TimelockTransferred stakedfrax_timelock_transferreds = 7;
|
||||||
|
repeated stakedfrax_Transfer stakedfrax_transfers = 8;
|
||||||
|
repeated stakedfrax_Withdraw stakedfrax_withdraws = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Calls {
|
||||||
|
repeated stakedfrax_AcceptTransferTimelockCall stakedfrax_call_accept_transfer_timelocks = 1;
|
||||||
|
repeated stakedfrax_ApproveCall stakedfrax_call_approves = 2;
|
||||||
|
repeated stakedfrax_DepositCall stakedfrax_call_deposits = 3;
|
||||||
|
repeated stakedfrax_DepositWithSignatureCall stakedfrax_call_deposit_with_signatures = 4;
|
||||||
|
repeated stakedfrax_MintCall stakedfrax_call_mints = 5;
|
||||||
|
repeated stakedfrax_PermitCall stakedfrax_call_permits = 6;
|
||||||
|
repeated stakedfrax_RedeemCall stakedfrax_call_redeems = 7;
|
||||||
|
repeated stakedfrax_RenounceTimelockCall stakedfrax_call_renounce_timelocks = 8;
|
||||||
|
repeated stakedfrax_SetMaxDistributionPerSecondPerAssetCall stakedfrax_call_set_max_distribution_per_second_per_assets = 9;
|
||||||
|
repeated stakedfrax_SyncRewardsAndDistributionCall stakedfrax_call_sync_rewards_and_distributions = 10;
|
||||||
|
repeated stakedfrax_TransferCall stakedfrax_call_transfers = 11;
|
||||||
|
repeated stakedfrax_TransferFromCall stakedfrax_call_transfer_froms = 12;
|
||||||
|
repeated stakedfrax_TransferTimelockCall stakedfrax_call_transfer_timelocks = 13;
|
||||||
|
repeated stakedfrax_WithdrawCall stakedfrax_call_withdraws = 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message stakedfrax_Approval {
|
||||||
|
string evt_tx_hash = 1;
|
||||||
|
uint32 evt_index = 2;
|
||||||
|
google.protobuf.Timestamp evt_block_time = 3;
|
||||||
|
uint64 evt_block_number = 4;
|
||||||
|
bytes owner = 5;
|
||||||
|
bytes spender = 6;
|
||||||
|
string amount = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_Deposit {
|
||||||
|
string evt_tx_hash = 1;
|
||||||
|
uint32 evt_index = 2;
|
||||||
|
google.protobuf.Timestamp evt_block_time = 3;
|
||||||
|
uint64 evt_block_number = 4;
|
||||||
|
bytes caller = 5;
|
||||||
|
bytes owner = 6;
|
||||||
|
string assets = 7;
|
||||||
|
string shares = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_DistributeRewards {
|
||||||
|
string evt_tx_hash = 1;
|
||||||
|
uint32 evt_index = 2;
|
||||||
|
google.protobuf.Timestamp evt_block_time = 3;
|
||||||
|
uint64 evt_block_number = 4;
|
||||||
|
string rewards_to_distribute = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_SetMaxDistributionPerSecondPerAsset {
|
||||||
|
string evt_tx_hash = 1;
|
||||||
|
uint32 evt_index = 2;
|
||||||
|
google.protobuf.Timestamp evt_block_time = 3;
|
||||||
|
uint64 evt_block_number = 4;
|
||||||
|
string old_max = 5;
|
||||||
|
string new_max = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_SyncRewards {
|
||||||
|
string evt_tx_hash = 1;
|
||||||
|
uint32 evt_index = 2;
|
||||||
|
google.protobuf.Timestamp evt_block_time = 3;
|
||||||
|
uint64 evt_block_number = 4;
|
||||||
|
uint64 cycle_end = 5;
|
||||||
|
uint64 last_sync = 6;
|
||||||
|
string reward_cycle_amount = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_TimelockTransferStarted {
|
||||||
|
string evt_tx_hash = 1;
|
||||||
|
uint32 evt_index = 2;
|
||||||
|
google.protobuf.Timestamp evt_block_time = 3;
|
||||||
|
uint64 evt_block_number = 4;
|
||||||
|
bytes previous_timelock = 5;
|
||||||
|
bytes new_timelock = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_TimelockTransferred {
|
||||||
|
string evt_tx_hash = 1;
|
||||||
|
uint32 evt_index = 2;
|
||||||
|
google.protobuf.Timestamp evt_block_time = 3;
|
||||||
|
uint64 evt_block_number = 4;
|
||||||
|
bytes previous_timelock = 5;
|
||||||
|
bytes new_timelock = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_Transfer {
|
||||||
|
string evt_tx_hash = 1;
|
||||||
|
uint32 evt_index = 2;
|
||||||
|
google.protobuf.Timestamp evt_block_time = 3;
|
||||||
|
uint64 evt_block_number = 4;
|
||||||
|
bytes from = 5;
|
||||||
|
bytes to = 6;
|
||||||
|
string amount = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_Withdraw {
|
||||||
|
string evt_tx_hash = 1;
|
||||||
|
uint32 evt_index = 2;
|
||||||
|
google.protobuf.Timestamp evt_block_time = 3;
|
||||||
|
uint64 evt_block_number = 4;
|
||||||
|
bytes caller = 5;
|
||||||
|
bytes receiver = 6;
|
||||||
|
bytes owner = 7;
|
||||||
|
string assets = 8;
|
||||||
|
string shares = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_AcceptTransferTimelockCall {
|
||||||
|
string call_tx_hash = 1;
|
||||||
|
google.protobuf.Timestamp call_block_time = 2;
|
||||||
|
uint64 call_block_number = 3;
|
||||||
|
uint64 call_ordinal = 4;
|
||||||
|
bool call_success = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_ApproveCall {
|
||||||
|
string call_tx_hash = 1;
|
||||||
|
google.protobuf.Timestamp call_block_time = 2;
|
||||||
|
uint64 call_block_number = 3;
|
||||||
|
uint64 call_ordinal = 4;
|
||||||
|
bool call_success = 5;
|
||||||
|
bytes spender = 6;
|
||||||
|
string amount = 7;
|
||||||
|
bool output_param0 = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_DepositCall {
|
||||||
|
string call_tx_hash = 1;
|
||||||
|
google.protobuf.Timestamp call_block_time = 2;
|
||||||
|
uint64 call_block_number = 3;
|
||||||
|
uint64 call_ordinal = 4;
|
||||||
|
bool call_success = 5;
|
||||||
|
string u_assets = 6;
|
||||||
|
bytes u_receiver = 7;
|
||||||
|
string output__shares = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_DepositWithSignatureCall {
|
||||||
|
string call_tx_hash = 1;
|
||||||
|
google.protobuf.Timestamp call_block_time = 2;
|
||||||
|
uint64 call_block_number = 3;
|
||||||
|
uint64 call_ordinal = 4;
|
||||||
|
bool call_success = 5;
|
||||||
|
string u_assets = 6;
|
||||||
|
bytes u_receiver = 7;
|
||||||
|
string u_deadline = 8;
|
||||||
|
bool u_approve_max = 9;
|
||||||
|
uint64 u_v = 10;
|
||||||
|
bytes u_r = 11;
|
||||||
|
bytes u_s = 12;
|
||||||
|
string output__shares = 13;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_MintCall {
|
||||||
|
string call_tx_hash = 1;
|
||||||
|
google.protobuf.Timestamp call_block_time = 2;
|
||||||
|
uint64 call_block_number = 3;
|
||||||
|
uint64 call_ordinal = 4;
|
||||||
|
bool call_success = 5;
|
||||||
|
string u_shares = 6;
|
||||||
|
bytes u_receiver = 7;
|
||||||
|
string output__assets = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_PermitCall {
|
||||||
|
string call_tx_hash = 1;
|
||||||
|
google.protobuf.Timestamp call_block_time = 2;
|
||||||
|
uint64 call_block_number = 3;
|
||||||
|
uint64 call_ordinal = 4;
|
||||||
|
bool call_success = 5;
|
||||||
|
bytes owner = 6;
|
||||||
|
bytes spender = 7;
|
||||||
|
string value = 8;
|
||||||
|
string deadline = 9;
|
||||||
|
uint64 v = 10;
|
||||||
|
bytes r = 11;
|
||||||
|
bytes s = 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_RedeemCall {
|
||||||
|
string call_tx_hash = 1;
|
||||||
|
google.protobuf.Timestamp call_block_time = 2;
|
||||||
|
uint64 call_block_number = 3;
|
||||||
|
uint64 call_ordinal = 4;
|
||||||
|
bool call_success = 5;
|
||||||
|
string u_shares = 6;
|
||||||
|
bytes u_receiver = 7;
|
||||||
|
bytes u_owner = 8;
|
||||||
|
string output__assets = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_RenounceTimelockCall {
|
||||||
|
string call_tx_hash = 1;
|
||||||
|
google.protobuf.Timestamp call_block_time = 2;
|
||||||
|
uint64 call_block_number = 3;
|
||||||
|
uint64 call_ordinal = 4;
|
||||||
|
bool call_success = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_SetMaxDistributionPerSecondPerAssetCall {
|
||||||
|
string call_tx_hash = 1;
|
||||||
|
google.protobuf.Timestamp call_block_time = 2;
|
||||||
|
uint64 call_block_number = 3;
|
||||||
|
uint64 call_ordinal = 4;
|
||||||
|
bool call_success = 5;
|
||||||
|
string u_max_distribution_per_second_per_asset = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_SyncRewardsAndDistributionCall {
|
||||||
|
string call_tx_hash = 1;
|
||||||
|
google.protobuf.Timestamp call_block_time = 2;
|
||||||
|
uint64 call_block_number = 3;
|
||||||
|
uint64 call_ordinal = 4;
|
||||||
|
bool call_success = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_TransferCall {
|
||||||
|
string call_tx_hash = 1;
|
||||||
|
google.protobuf.Timestamp call_block_time = 2;
|
||||||
|
uint64 call_block_number = 3;
|
||||||
|
uint64 call_ordinal = 4;
|
||||||
|
bool call_success = 5;
|
||||||
|
bytes to = 6;
|
||||||
|
string amount = 7;
|
||||||
|
bool output_param0 = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_TransferFromCall {
|
||||||
|
string call_tx_hash = 1;
|
||||||
|
google.protobuf.Timestamp call_block_time = 2;
|
||||||
|
uint64 call_block_number = 3;
|
||||||
|
uint64 call_ordinal = 4;
|
||||||
|
bool call_success = 5;
|
||||||
|
bytes from = 6;
|
||||||
|
bytes to = 7;
|
||||||
|
string amount = 8;
|
||||||
|
bool output_param0 = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_TransferTimelockCall {
|
||||||
|
string call_tx_hash = 1;
|
||||||
|
google.protobuf.Timestamp call_block_time = 2;
|
||||||
|
uint64 call_block_number = 3;
|
||||||
|
uint64 call_ordinal = 4;
|
||||||
|
bool call_success = 5;
|
||||||
|
bytes u_new_timelock = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message stakedfrax_WithdrawCall {
|
||||||
|
string call_tx_hash = 1;
|
||||||
|
google.protobuf.Timestamp call_block_time = 2;
|
||||||
|
uint64 call_block_number = 3;
|
||||||
|
uint64 call_ordinal = 4;
|
||||||
|
bool call_success = 5;
|
||||||
|
string u_assets = 6;
|
||||||
|
bytes u_receiver = 7;
|
||||||
|
bytes u_owner = 8;
|
||||||
|
string output__shares = 9;
|
||||||
|
}
|
||||||
4
substreams/ethereum-sfrax/rust-toolchain.toml
Normal file
4
substreams/ethereum-sfrax/rust-toolchain.toml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[toolchain]
|
||||||
|
channel = "1.75"
|
||||||
|
components = ["rustfmt"]
|
||||||
|
targets = ["wasm32-unknown-unknown"]
|
||||||
2
substreams/ethereum-sfrax/src/abi/mod.rs
Normal file
2
substreams/ethereum-sfrax/src/abi/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#[allow(clippy::all)]
|
||||||
|
pub mod stakedfrax_contract;
|
||||||
5446
substreams/ethereum-sfrax/src/abi/stakedfrax_contract.rs
Normal file
5446
substreams/ethereum-sfrax/src/abi/stakedfrax_contract.rs
Normal file
File diff suppressed because it is too large
Load Diff
3
substreams/ethereum-sfrax/src/lib.rs
Normal file
3
substreams/ethereum-sfrax/src/lib.rs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
mod abi;
|
||||||
|
mod modules;
|
||||||
|
pub mod pb;
|
||||||
277
substreams/ethereum-sfrax/src/modules.rs
Normal file
277
substreams/ethereum-sfrax/src/modules.rs
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
use crate::abi;
|
||||||
|
use anyhow::Result;
|
||||||
|
use itertools::Itertools;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use substreams::{
|
||||||
|
hex,
|
||||||
|
pb::substreams::StoreDeltas,
|
||||||
|
store::{StoreAdd, StoreAddBigInt, StoreAddInt64, StoreGet, StoreGetInt64, StoreNew},
|
||||||
|
};
|
||||||
|
use substreams_ethereum::{
|
||||||
|
pb::eth::{self},
|
||||||
|
Event,
|
||||||
|
};
|
||||||
|
use tycho_substreams::{
|
||||||
|
balances::aggregate_balances_changes, contract::extract_contract_changes, prelude::*,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[substreams::handlers::map]
|
||||||
|
pub fn map_components(
|
||||||
|
params: String,
|
||||||
|
block: eth::v2::Block,
|
||||||
|
) -> Result<BlockTransactionProtocolComponents, anyhow::Error> {
|
||||||
|
let vault_address = hex::decode(params).unwrap();
|
||||||
|
let locked_asset = find_deployed_underlying_address(&vault_address).unwrap();
|
||||||
|
// We store these as a hashmap by tx hash since we need to agg by tx hash later
|
||||||
|
Ok(BlockTransactionProtocolComponents {
|
||||||
|
tx_components: block
|
||||||
|
.transactions()
|
||||||
|
.filter_map(|tx| {
|
||||||
|
let components = tx
|
||||||
|
.calls()
|
||||||
|
.filter(|call| !call.call.state_reverted)
|
||||||
|
.filter_map(|_| {
|
||||||
|
// address doesn't exist before contract deployment, hence the first tx with
|
||||||
|
// a log.address = vault_address is the deployment tx
|
||||||
|
if is_deployment_tx(tx, &vault_address) {
|
||||||
|
Some(
|
||||||
|
ProtocolComponent::at_contract(&vault_address, &tx.into())
|
||||||
|
.with_tokens(&[
|
||||||
|
locked_asset.as_slice(),
|
||||||
|
vault_address.as_slice(),
|
||||||
|
])
|
||||||
|
.as_swap_type("sfrax_vault", ImplementationType::Vm),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if !components.is_empty() {
|
||||||
|
Some(TransactionProtocolComponents { tx: Some(tx.into()), components })
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[substreams::handlers::store]
|
||||||
|
pub fn store_components(map: BlockTransactionProtocolComponents, store: StoreAddInt64) {
|
||||||
|
store.add_many(
|
||||||
|
0,
|
||||||
|
&map.tx_components
|
||||||
|
.iter()
|
||||||
|
.flat_map(|tx_components| &tx_components.components)
|
||||||
|
.map(|component| format!("pool:{0}", component.id))
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[substreams::handlers::map]
|
||||||
|
pub fn map_relative_balances(
|
||||||
|
block: eth::v2::Block,
|
||||||
|
store: StoreGetInt64,
|
||||||
|
) -> Result<BlockBalanceDeltas, anyhow::Error> {
|
||||||
|
let balance_deltas = block
|
||||||
|
.logs()
|
||||||
|
.flat_map(|vault_log| {
|
||||||
|
let mut deltas = Vec::new();
|
||||||
|
|
||||||
|
if let Some(ev) =
|
||||||
|
abi::stakedfrax_contract::events::Withdraw::match_and_decode(vault_log.log)
|
||||||
|
{
|
||||||
|
let address_bytes_be = vault_log.address();
|
||||||
|
let address_hex = format!("0x{}", hex::encode(address_bytes_be));
|
||||||
|
if store
|
||||||
|
.get_last(format!("pool:{}", address_hex))
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
deltas.extend_from_slice(&[
|
||||||
|
BalanceDelta {
|
||||||
|
ord: vault_log.ordinal(),
|
||||||
|
tx: Some(vault_log.receipt.transaction.into()),
|
||||||
|
token: find_deployed_underlying_address(address_bytes_be)
|
||||||
|
.unwrap()
|
||||||
|
.to_vec(),
|
||||||
|
delta: ev.assets.neg().to_signed_bytes_be(),
|
||||||
|
component_id: address_hex.as_bytes().to_vec(),
|
||||||
|
},
|
||||||
|
BalanceDelta {
|
||||||
|
ord: vault_log.ordinal(),
|
||||||
|
tx: Some(vault_log.receipt.transaction.into()),
|
||||||
|
token: address_bytes_be.to_vec(),
|
||||||
|
delta: ev.shares.neg().to_signed_bytes_be(),
|
||||||
|
component_id: address_hex.as_bytes().to_vec(),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
substreams::log::debug!(
|
||||||
|
"Withdraw: vault: {}, frax:- {}, sfrax:- {}",
|
||||||
|
address_hex,
|
||||||
|
ev.assets,
|
||||||
|
ev.shares
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if let Some(ev) =
|
||||||
|
abi::stakedfrax_contract::events::Deposit::match_and_decode(vault_log.log)
|
||||||
|
{
|
||||||
|
let address_bytes_be = vault_log.address();
|
||||||
|
let address_hex = format!("0x{}", hex::encode(address_bytes_be));
|
||||||
|
|
||||||
|
if store
|
||||||
|
.get_last(format!("pool:{}", address_hex))
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
deltas.extend_from_slice(&[
|
||||||
|
BalanceDelta {
|
||||||
|
ord: vault_log.ordinal(),
|
||||||
|
tx: Some(vault_log.receipt.transaction.into()),
|
||||||
|
token: find_deployed_underlying_address(address_bytes_be)
|
||||||
|
.unwrap()
|
||||||
|
.to_vec(),
|
||||||
|
delta: ev.assets.to_signed_bytes_be(),
|
||||||
|
component_id: address_hex.as_bytes().to_vec(),
|
||||||
|
},
|
||||||
|
BalanceDelta {
|
||||||
|
ord: vault_log.ordinal(),
|
||||||
|
tx: Some(vault_log.receipt.transaction.into()),
|
||||||
|
token: address_bytes_be.to_vec(),
|
||||||
|
delta: ev.shares.to_signed_bytes_be(),
|
||||||
|
component_id: address_hex.as_bytes().to_vec(),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
substreams::log::debug!(
|
||||||
|
"Deposit: vault: {}, frax:+ {}, sfrax:+ {}",
|
||||||
|
address_hex,
|
||||||
|
ev.assets,
|
||||||
|
ev.shares
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if let Some(ev) =
|
||||||
|
abi::stakedfrax_contract::events::DistributeRewards::match_and_decode(vault_log.log)
|
||||||
|
{
|
||||||
|
let address_bytes_be = vault_log.address();
|
||||||
|
let address_hex = format!("0x{}", hex::encode(address_bytes_be));
|
||||||
|
|
||||||
|
if store
|
||||||
|
.get_last(format!("pool:{}", address_hex))
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
deltas.extend_from_slice(&[BalanceDelta {
|
||||||
|
ord: vault_log.ordinal(),
|
||||||
|
tx: Some(vault_log.receipt.transaction.into()),
|
||||||
|
token: address_bytes_be.to_vec(),
|
||||||
|
delta: ev
|
||||||
|
.rewards_to_distribute
|
||||||
|
.to_signed_bytes_be(),
|
||||||
|
component_id: address_hex.as_bytes().to_vec(),
|
||||||
|
}]);
|
||||||
|
// Log token and amount without encoding
|
||||||
|
substreams::log::debug!(
|
||||||
|
"DistributeRewards: vault: {}, frax:+ {}",
|
||||||
|
address_hex,
|
||||||
|
ev.rewards_to_distribute
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deltas
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
Ok(BlockBalanceDeltas { balance_deltas })
|
||||||
|
}
|
||||||
|
|
||||||
|
#[substreams::handlers::store]
|
||||||
|
pub fn store_balances(deltas: BlockBalanceDeltas, store: StoreAddBigInt) {
|
||||||
|
tycho_substreams::balances::store_balance_changes(deltas, store);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[substreams::handlers::map]
|
||||||
|
pub fn map_protocol_changes(
|
||||||
|
block: eth::v2::Block,
|
||||||
|
grouped_components: BlockTransactionProtocolComponents,
|
||||||
|
deltas: BlockBalanceDeltas,
|
||||||
|
components_store: StoreGetInt64,
|
||||||
|
balance_store: StoreDeltas,
|
||||||
|
) -> Result<BlockChanges, anyhow::Error> {
|
||||||
|
let mut transaction_contract: HashMap<u64, TransactionChanges> = HashMap::new();
|
||||||
|
|
||||||
|
grouped_components
|
||||||
|
.tx_components
|
||||||
|
.iter()
|
||||||
|
.for_each(|tx_component| {
|
||||||
|
let tx = tx_component.tx.as_ref().unwrap();
|
||||||
|
transaction_contract
|
||||||
|
.entry(tx.index)
|
||||||
|
.or_insert_with(|| TransactionChanges::new(tx))
|
||||||
|
.component_changes
|
||||||
|
.extend_from_slice(&tx_component.components);
|
||||||
|
});
|
||||||
|
|
||||||
|
aggregate_balances_changes(balance_store, deltas)
|
||||||
|
.into_iter()
|
||||||
|
.for_each(|(_, (tx, balances))| {
|
||||||
|
transaction_contract
|
||||||
|
.entry(tx.index)
|
||||||
|
.or_insert_with(|| TransactionChanges::new(&tx))
|
||||||
|
.balance_changes
|
||||||
|
.extend(balances.into_values());
|
||||||
|
});
|
||||||
|
|
||||||
|
extract_contract_changes(
|
||||||
|
&block,
|
||||||
|
|addr| {
|
||||||
|
components_store
|
||||||
|
.get_last(format!("pool:0x{0}", hex::encode(addr)))
|
||||||
|
.is_some()
|
||||||
|
},
|
||||||
|
&mut transaction_contract,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(BlockChanges {
|
||||||
|
block: Some((&block).into()),
|
||||||
|
changes: transaction_contract
|
||||||
|
.drain()
|
||||||
|
.sorted_unstable_by_key(|(index, _)| *index)
|
||||||
|
.filter_map(|(_, change)| {
|
||||||
|
if change.contract_changes.is_empty() &&
|
||||||
|
change.component_changes.is_empty() &&
|
||||||
|
change.balance_changes.is_empty()
|
||||||
|
{
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(change)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_deployment_tx(tx: ð::v2::TransactionTrace, vault_address: &[u8]) -> bool {
|
||||||
|
let created_accounts = tx
|
||||||
|
.calls
|
||||||
|
.iter()
|
||||||
|
.flat_map(|call| {
|
||||||
|
call.account_creations
|
||||||
|
.iter()
|
||||||
|
.map(|ac| ac.account.to_owned())
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if let Some(deployed_address) = created_accounts.first() {
|
||||||
|
return deployed_address.as_slice() == vault_address;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_deployed_underlying_address(vault_address: &[u8]) -> Option<[u8; 20]> {
|
||||||
|
match vault_address {
|
||||||
|
hex!("A663B02CF0a4b149d2aD41910CB81e23e1c41c32") => {
|
||||||
|
Some(hex!("853d955aCEf822Db058eb8505911ED77F175b99e"))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
508
substreams/ethereum-sfrax/src/pb/contract.v1.rs
Normal file
508
substreams/ethereum-sfrax/src/pb/contract.v1.rs
Normal file
@@ -0,0 +1,508 @@
|
|||||||
|
// @generated
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct Events {
|
||||||
|
#[prost(message, repeated, tag="1")]
|
||||||
|
pub stakedfrax_approvals: ::prost::alloc::vec::Vec<StakedfraxApproval>,
|
||||||
|
#[prost(message, repeated, tag="2")]
|
||||||
|
pub stakedfrax_deposits: ::prost::alloc::vec::Vec<StakedfraxDeposit>,
|
||||||
|
#[prost(message, repeated, tag="3")]
|
||||||
|
pub stakedfrax_distribute_rewards: ::prost::alloc::vec::Vec<StakedfraxDistributeRewards>,
|
||||||
|
#[prost(message, repeated, tag="4")]
|
||||||
|
pub stakedfrax_set_max_distribution_per_second_per_assets: ::prost::alloc::vec::Vec<StakedfraxSetMaxDistributionPerSecondPerAsset>,
|
||||||
|
#[prost(message, repeated, tag="5")]
|
||||||
|
pub stakedfrax_sync_rewards: ::prost::alloc::vec::Vec<StakedfraxSyncRewards>,
|
||||||
|
#[prost(message, repeated, tag="6")]
|
||||||
|
pub stakedfrax_timelock_transfer_starteds: ::prost::alloc::vec::Vec<StakedfraxTimelockTransferStarted>,
|
||||||
|
#[prost(message, repeated, tag="7")]
|
||||||
|
pub stakedfrax_timelock_transferreds: ::prost::alloc::vec::Vec<StakedfraxTimelockTransferred>,
|
||||||
|
#[prost(message, repeated, tag="8")]
|
||||||
|
pub stakedfrax_transfers: ::prost::alloc::vec::Vec<StakedfraxTransfer>,
|
||||||
|
#[prost(message, repeated, tag="9")]
|
||||||
|
pub stakedfrax_withdraws: ::prost::alloc::vec::Vec<StakedfraxWithdraw>,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct Calls {
|
||||||
|
#[prost(message, repeated, tag="1")]
|
||||||
|
pub stakedfrax_call_accept_transfer_timelocks: ::prost::alloc::vec::Vec<StakedfraxAcceptTransferTimelockCall>,
|
||||||
|
#[prost(message, repeated, tag="2")]
|
||||||
|
pub stakedfrax_call_approves: ::prost::alloc::vec::Vec<StakedfraxApproveCall>,
|
||||||
|
#[prost(message, repeated, tag="3")]
|
||||||
|
pub stakedfrax_call_deposits: ::prost::alloc::vec::Vec<StakedfraxDepositCall>,
|
||||||
|
#[prost(message, repeated, tag="4")]
|
||||||
|
pub stakedfrax_call_deposit_with_signatures: ::prost::alloc::vec::Vec<StakedfraxDepositWithSignatureCall>,
|
||||||
|
#[prost(message, repeated, tag="5")]
|
||||||
|
pub stakedfrax_call_mints: ::prost::alloc::vec::Vec<StakedfraxMintCall>,
|
||||||
|
#[prost(message, repeated, tag="6")]
|
||||||
|
pub stakedfrax_call_permits: ::prost::alloc::vec::Vec<StakedfraxPermitCall>,
|
||||||
|
#[prost(message, repeated, tag="7")]
|
||||||
|
pub stakedfrax_call_redeems: ::prost::alloc::vec::Vec<StakedfraxRedeemCall>,
|
||||||
|
#[prost(message, repeated, tag="8")]
|
||||||
|
pub stakedfrax_call_renounce_timelocks: ::prost::alloc::vec::Vec<StakedfraxRenounceTimelockCall>,
|
||||||
|
#[prost(message, repeated, tag="9")]
|
||||||
|
pub stakedfrax_call_set_max_distribution_per_second_per_assets: ::prost::alloc::vec::Vec<StakedfraxSetMaxDistributionPerSecondPerAssetCall>,
|
||||||
|
#[prost(message, repeated, tag="10")]
|
||||||
|
pub stakedfrax_call_sync_rewards_and_distributions: ::prost::alloc::vec::Vec<StakedfraxSyncRewardsAndDistributionCall>,
|
||||||
|
#[prost(message, repeated, tag="11")]
|
||||||
|
pub stakedfrax_call_transfers: ::prost::alloc::vec::Vec<StakedfraxTransferCall>,
|
||||||
|
#[prost(message, repeated, tag="12")]
|
||||||
|
pub stakedfrax_call_transfer_froms: ::prost::alloc::vec::Vec<StakedfraxTransferFromCall>,
|
||||||
|
#[prost(message, repeated, tag="13")]
|
||||||
|
pub stakedfrax_call_transfer_timelocks: ::prost::alloc::vec::Vec<StakedfraxTransferTimelockCall>,
|
||||||
|
#[prost(message, repeated, tag="14")]
|
||||||
|
pub stakedfrax_call_withdraws: ::prost::alloc::vec::Vec<StakedfraxWithdrawCall>,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxApproval {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub evt_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(uint32, tag="2")]
|
||||||
|
pub evt_index: u32,
|
||||||
|
#[prost(message, optional, tag="3")]
|
||||||
|
pub evt_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub evt_block_number: u64,
|
||||||
|
#[prost(bytes="vec", tag="5")]
|
||||||
|
pub owner: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(bytes="vec", tag="6")]
|
||||||
|
pub spender: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(string, tag="7")]
|
||||||
|
pub amount: ::prost::alloc::string::String,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxDeposit {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub evt_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(uint32, tag="2")]
|
||||||
|
pub evt_index: u32,
|
||||||
|
#[prost(message, optional, tag="3")]
|
||||||
|
pub evt_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub evt_block_number: u64,
|
||||||
|
#[prost(bytes="vec", tag="5")]
|
||||||
|
pub caller: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(bytes="vec", tag="6")]
|
||||||
|
pub owner: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(string, tag="7")]
|
||||||
|
pub assets: ::prost::alloc::string::String,
|
||||||
|
#[prost(string, tag="8")]
|
||||||
|
pub shares: ::prost::alloc::string::String,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxDistributeRewards {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub evt_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(uint32, tag="2")]
|
||||||
|
pub evt_index: u32,
|
||||||
|
#[prost(message, optional, tag="3")]
|
||||||
|
pub evt_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub evt_block_number: u64,
|
||||||
|
#[prost(string, tag="5")]
|
||||||
|
pub rewards_to_distribute: ::prost::alloc::string::String,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxSetMaxDistributionPerSecondPerAsset {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub evt_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(uint32, tag="2")]
|
||||||
|
pub evt_index: u32,
|
||||||
|
#[prost(message, optional, tag="3")]
|
||||||
|
pub evt_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub evt_block_number: u64,
|
||||||
|
#[prost(string, tag="5")]
|
||||||
|
pub old_max: ::prost::alloc::string::String,
|
||||||
|
#[prost(string, tag="6")]
|
||||||
|
pub new_max: ::prost::alloc::string::String,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxSyncRewards {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub evt_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(uint32, tag="2")]
|
||||||
|
pub evt_index: u32,
|
||||||
|
#[prost(message, optional, tag="3")]
|
||||||
|
pub evt_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub evt_block_number: u64,
|
||||||
|
#[prost(uint64, tag="5")]
|
||||||
|
pub cycle_end: u64,
|
||||||
|
#[prost(uint64, tag="6")]
|
||||||
|
pub last_sync: u64,
|
||||||
|
#[prost(string, tag="7")]
|
||||||
|
pub reward_cycle_amount: ::prost::alloc::string::String,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxTimelockTransferStarted {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub evt_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(uint32, tag="2")]
|
||||||
|
pub evt_index: u32,
|
||||||
|
#[prost(message, optional, tag="3")]
|
||||||
|
pub evt_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub evt_block_number: u64,
|
||||||
|
#[prost(bytes="vec", tag="5")]
|
||||||
|
pub previous_timelock: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(bytes="vec", tag="6")]
|
||||||
|
pub new_timelock: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxTimelockTransferred {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub evt_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(uint32, tag="2")]
|
||||||
|
pub evt_index: u32,
|
||||||
|
#[prost(message, optional, tag="3")]
|
||||||
|
pub evt_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub evt_block_number: u64,
|
||||||
|
#[prost(bytes="vec", tag="5")]
|
||||||
|
pub previous_timelock: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(bytes="vec", tag="6")]
|
||||||
|
pub new_timelock: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxTransfer {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub evt_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(uint32, tag="2")]
|
||||||
|
pub evt_index: u32,
|
||||||
|
#[prost(message, optional, tag="3")]
|
||||||
|
pub evt_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub evt_block_number: u64,
|
||||||
|
#[prost(bytes="vec", tag="5")]
|
||||||
|
pub from: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(bytes="vec", tag="6")]
|
||||||
|
pub to: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(string, tag="7")]
|
||||||
|
pub amount: ::prost::alloc::string::String,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxWithdraw {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub evt_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(uint32, tag="2")]
|
||||||
|
pub evt_index: u32,
|
||||||
|
#[prost(message, optional, tag="3")]
|
||||||
|
pub evt_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub evt_block_number: u64,
|
||||||
|
#[prost(bytes="vec", tag="5")]
|
||||||
|
pub caller: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(bytes="vec", tag="6")]
|
||||||
|
pub receiver: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(bytes="vec", tag="7")]
|
||||||
|
pub owner: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(string, tag="8")]
|
||||||
|
pub assets: ::prost::alloc::string::String,
|
||||||
|
#[prost(string, tag="9")]
|
||||||
|
pub shares: ::prost::alloc::string::String,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxAcceptTransferTimelockCall {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub call_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(message, optional, tag="2")]
|
||||||
|
pub call_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="3")]
|
||||||
|
pub call_block_number: u64,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub call_ordinal: u64,
|
||||||
|
#[prost(bool, tag="5")]
|
||||||
|
pub call_success: bool,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxApproveCall {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub call_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(message, optional, tag="2")]
|
||||||
|
pub call_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="3")]
|
||||||
|
pub call_block_number: u64,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub call_ordinal: u64,
|
||||||
|
#[prost(bool, tag="5")]
|
||||||
|
pub call_success: bool,
|
||||||
|
#[prost(bytes="vec", tag="6")]
|
||||||
|
pub spender: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(string, tag="7")]
|
||||||
|
pub amount: ::prost::alloc::string::String,
|
||||||
|
#[prost(bool, tag="8")]
|
||||||
|
pub output_param0: bool,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxDepositCall {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub call_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(message, optional, tag="2")]
|
||||||
|
pub call_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="3")]
|
||||||
|
pub call_block_number: u64,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub call_ordinal: u64,
|
||||||
|
#[prost(bool, tag="5")]
|
||||||
|
pub call_success: bool,
|
||||||
|
#[prost(string, tag="6")]
|
||||||
|
pub u_assets: ::prost::alloc::string::String,
|
||||||
|
#[prost(bytes="vec", tag="7")]
|
||||||
|
pub u_receiver: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(string, tag="8")]
|
||||||
|
pub output_shares: ::prost::alloc::string::String,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxDepositWithSignatureCall {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub call_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(message, optional, tag="2")]
|
||||||
|
pub call_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="3")]
|
||||||
|
pub call_block_number: u64,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub call_ordinal: u64,
|
||||||
|
#[prost(bool, tag="5")]
|
||||||
|
pub call_success: bool,
|
||||||
|
#[prost(string, tag="6")]
|
||||||
|
pub u_assets: ::prost::alloc::string::String,
|
||||||
|
#[prost(bytes="vec", tag="7")]
|
||||||
|
pub u_receiver: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(string, tag="8")]
|
||||||
|
pub u_deadline: ::prost::alloc::string::String,
|
||||||
|
#[prost(bool, tag="9")]
|
||||||
|
pub u_approve_max: bool,
|
||||||
|
#[prost(uint64, tag="10")]
|
||||||
|
pub u_v: u64,
|
||||||
|
#[prost(bytes="vec", tag="11")]
|
||||||
|
pub u_r: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(bytes="vec", tag="12")]
|
||||||
|
pub u_s: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(string, tag="13")]
|
||||||
|
pub output_shares: ::prost::alloc::string::String,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxMintCall {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub call_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(message, optional, tag="2")]
|
||||||
|
pub call_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="3")]
|
||||||
|
pub call_block_number: u64,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub call_ordinal: u64,
|
||||||
|
#[prost(bool, tag="5")]
|
||||||
|
pub call_success: bool,
|
||||||
|
#[prost(string, tag="6")]
|
||||||
|
pub u_shares: ::prost::alloc::string::String,
|
||||||
|
#[prost(bytes="vec", tag="7")]
|
||||||
|
pub u_receiver: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(string, tag="8")]
|
||||||
|
pub output_assets: ::prost::alloc::string::String,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxPermitCall {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub call_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(message, optional, tag="2")]
|
||||||
|
pub call_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="3")]
|
||||||
|
pub call_block_number: u64,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub call_ordinal: u64,
|
||||||
|
#[prost(bool, tag="5")]
|
||||||
|
pub call_success: bool,
|
||||||
|
#[prost(bytes="vec", tag="6")]
|
||||||
|
pub owner: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(bytes="vec", tag="7")]
|
||||||
|
pub spender: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(string, tag="8")]
|
||||||
|
pub value: ::prost::alloc::string::String,
|
||||||
|
#[prost(string, tag="9")]
|
||||||
|
pub deadline: ::prost::alloc::string::String,
|
||||||
|
#[prost(uint64, tag="10")]
|
||||||
|
pub v: u64,
|
||||||
|
#[prost(bytes="vec", tag="11")]
|
||||||
|
pub r: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(bytes="vec", tag="12")]
|
||||||
|
pub s: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxRedeemCall {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub call_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(message, optional, tag="2")]
|
||||||
|
pub call_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="3")]
|
||||||
|
pub call_block_number: u64,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub call_ordinal: u64,
|
||||||
|
#[prost(bool, tag="5")]
|
||||||
|
pub call_success: bool,
|
||||||
|
#[prost(string, tag="6")]
|
||||||
|
pub u_shares: ::prost::alloc::string::String,
|
||||||
|
#[prost(bytes="vec", tag="7")]
|
||||||
|
pub u_receiver: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(bytes="vec", tag="8")]
|
||||||
|
pub u_owner: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(string, tag="9")]
|
||||||
|
pub output_assets: ::prost::alloc::string::String,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxRenounceTimelockCall {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub call_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(message, optional, tag="2")]
|
||||||
|
pub call_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="3")]
|
||||||
|
pub call_block_number: u64,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub call_ordinal: u64,
|
||||||
|
#[prost(bool, tag="5")]
|
||||||
|
pub call_success: bool,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxSetMaxDistributionPerSecondPerAssetCall {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub call_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(message, optional, tag="2")]
|
||||||
|
pub call_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="3")]
|
||||||
|
pub call_block_number: u64,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub call_ordinal: u64,
|
||||||
|
#[prost(bool, tag="5")]
|
||||||
|
pub call_success: bool,
|
||||||
|
#[prost(string, tag="6")]
|
||||||
|
pub u_max_distribution_per_second_per_asset: ::prost::alloc::string::String,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxSyncRewardsAndDistributionCall {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub call_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(message, optional, tag="2")]
|
||||||
|
pub call_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="3")]
|
||||||
|
pub call_block_number: u64,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub call_ordinal: u64,
|
||||||
|
#[prost(bool, tag="5")]
|
||||||
|
pub call_success: bool,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxTransferCall {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub call_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(message, optional, tag="2")]
|
||||||
|
pub call_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="3")]
|
||||||
|
pub call_block_number: u64,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub call_ordinal: u64,
|
||||||
|
#[prost(bool, tag="5")]
|
||||||
|
pub call_success: bool,
|
||||||
|
#[prost(bytes="vec", tag="6")]
|
||||||
|
pub to: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(string, tag="7")]
|
||||||
|
pub amount: ::prost::alloc::string::String,
|
||||||
|
#[prost(bool, tag="8")]
|
||||||
|
pub output_param0: bool,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxTransferFromCall {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub call_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(message, optional, tag="2")]
|
||||||
|
pub call_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="3")]
|
||||||
|
pub call_block_number: u64,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub call_ordinal: u64,
|
||||||
|
#[prost(bool, tag="5")]
|
||||||
|
pub call_success: bool,
|
||||||
|
#[prost(bytes="vec", tag="6")]
|
||||||
|
pub from: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(bytes="vec", tag="7")]
|
||||||
|
pub to: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(string, tag="8")]
|
||||||
|
pub amount: ::prost::alloc::string::String,
|
||||||
|
#[prost(bool, tag="9")]
|
||||||
|
pub output_param0: bool,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxTransferTimelockCall {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub call_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(message, optional, tag="2")]
|
||||||
|
pub call_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="3")]
|
||||||
|
pub call_block_number: u64,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub call_ordinal: u64,
|
||||||
|
#[prost(bool, tag="5")]
|
||||||
|
pub call_success: bool,
|
||||||
|
#[prost(bytes="vec", tag="6")]
|
||||||
|
pub u_new_timelock: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct StakedfraxWithdrawCall {
|
||||||
|
#[prost(string, tag="1")]
|
||||||
|
pub call_tx_hash: ::prost::alloc::string::String,
|
||||||
|
#[prost(message, optional, tag="2")]
|
||||||
|
pub call_block_time: ::core::option::Option<::prost_types::Timestamp>,
|
||||||
|
#[prost(uint64, tag="3")]
|
||||||
|
pub call_block_number: u64,
|
||||||
|
#[prost(uint64, tag="4")]
|
||||||
|
pub call_ordinal: u64,
|
||||||
|
#[prost(bool, tag="5")]
|
||||||
|
pub call_success: bool,
|
||||||
|
#[prost(string, tag="6")]
|
||||||
|
pub u_assets: ::prost::alloc::string::String,
|
||||||
|
#[prost(bytes="vec", tag="7")]
|
||||||
|
pub u_receiver: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(bytes="vec", tag="8")]
|
||||||
|
pub u_owner: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(string, tag="9")]
|
||||||
|
pub output_shares: ::prost::alloc::string::String,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct RewardCycle {
|
||||||
|
#[prost(uint64, tag="1")]
|
||||||
|
pub ord: u64,
|
||||||
|
#[prost(bytes="vec", tag="2")]
|
||||||
|
pub reward_rate: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
#[prost(string, tag="3")]
|
||||||
|
pub component_id: ::prost::alloc::string::String,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct BlockRewardCycles {
|
||||||
|
#[prost(message, repeated, tag="1")]
|
||||||
|
pub reward_cycles: ::prost::alloc::vec::Vec<RewardCycle>,
|
||||||
|
}
|
||||||
|
// @@protoc_insertion_point(module)
|
||||||
18
substreams/ethereum-sfrax/src/pb/mod.rs
Normal file
18
substreams/ethereum-sfrax/src/pb/mod.rs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#[allow(clippy::all)]
|
||||||
|
// @generated
|
||||||
|
pub mod contract {
|
||||||
|
// @@protoc_insertion_point(attribute:contract.v1)
|
||||||
|
pub mod v1 {
|
||||||
|
include!("contract.v1.rs");
|
||||||
|
// @@protoc_insertion_point(contract.v1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub mod tycho {
|
||||||
|
pub mod evm {
|
||||||
|
// @@protoc_insertion_point(attribute:tycho.evm.v1)
|
||||||
|
pub mod v1 {
|
||||||
|
include!("tycho.evm.v1.rs");
|
||||||
|
// @@protoc_insertion_point(tycho.evm.v1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
373
substreams/ethereum-sfrax/src/pb/tycho.evm.v1.rs
Normal file
373
substreams/ethereum-sfrax/src/pb/tycho.evm.v1.rs
Normal file
@@ -0,0 +1,373 @@
|
|||||||
|
// @generated
|
||||||
|
// WARNING: DEPRECATED. Please use common.proto's TransactionChanges and BlockChanges instead.
|
||||||
|
// This file contains proto definitions specific to the VM integration.
|
||||||
|
|
||||||
|
/// A set of changes aggregated by transaction.
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct TransactionContractChanges {
|
||||||
|
/// The transaction instance that results in the changes.
|
||||||
|
#[prost(message, optional, tag = "1")]
|
||||||
|
pub tx: ::core::option::Option<Transaction>,
|
||||||
|
/// Contains the changes induced by the above transaction, aggregated on a per-contract basis.
|
||||||
|
#[prost(message, repeated, tag = "2")]
|
||||||
|
pub contract_changes: ::prost::alloc::vec::Vec<ContractChange>,
|
||||||
|
/// An array of newly added components.
|
||||||
|
#[prost(message, repeated, tag = "3")]
|
||||||
|
pub component_changes: ::prost::alloc::vec::Vec<ProtocolComponent>,
|
||||||
|
/// An array of balance changes to components.
|
||||||
|
#[prost(message, repeated, tag = "4")]
|
||||||
|
pub balance_changes: ::prost::alloc::vec::Vec<BalanceChange>,
|
||||||
|
}
|
||||||
|
/// A set of transaction changes within a single block.
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct BlockContractChanges {
|
||||||
|
/// The block for which these changes are collectively computed.
|
||||||
|
#[prost(message, optional, tag = "1")]
|
||||||
|
pub block: ::core::option::Option<Block>,
|
||||||
|
/// The set of transaction changes observed in the specified block.
|
||||||
|
#[prost(message, repeated, tag = "2")]
|
||||||
|
pub changes: ::prost::alloc::vec::Vec<TransactionContractChanges>,
|
||||||
|
}
|
||||||
|
// This file contains the proto definitions for Substreams common to all integrations.
|
||||||
|
|
||||||
|
/// A struct describing a block.
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct Block {
|
||||||
|
/// The blocks hash.
|
||||||
|
#[prost(bytes = "vec", tag = "1")]
|
||||||
|
pub hash: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
/// The parent blocks hash.
|
||||||
|
#[prost(bytes = "vec", tag = "2")]
|
||||||
|
pub parent_hash: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
/// The block number.
|
||||||
|
#[prost(uint64, tag = "3")]
|
||||||
|
pub number: u64,
|
||||||
|
/// The block timestamp.
|
||||||
|
#[prost(uint64, tag = "4")]
|
||||||
|
pub ts: u64,
|
||||||
|
}
|
||||||
|
/// A struct describing a transaction.
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct Transaction {
|
||||||
|
/// The transaction hash.
|
||||||
|
#[prost(bytes = "vec", tag = "1")]
|
||||||
|
pub hash: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
/// The sender of the transaction.
|
||||||
|
#[prost(bytes = "vec", tag = "2")]
|
||||||
|
pub from: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
/// The receiver of the transaction.
|
||||||
|
#[prost(bytes = "vec", tag = "3")]
|
||||||
|
pub to: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
/// The transactions index within the block.
|
||||||
|
/// TODO: should this be uint32? to match the type from the native substream type?
|
||||||
|
#[prost(uint64, tag = "4")]
|
||||||
|
pub index: u64,
|
||||||
|
}
|
||||||
|
/// A custom struct representing an arbitrary attribute of a protocol component.
|
||||||
|
/// This is mainly used by the native integration to track the necessary information about the protocol.
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct Attribute {
|
||||||
|
/// The name of the attribute.
|
||||||
|
#[prost(string, tag = "1")]
|
||||||
|
pub name: ::prost::alloc::string::String,
|
||||||
|
/// The value of the attribute.
|
||||||
|
#[prost(bytes = "vec", tag = "2")]
|
||||||
|
pub value: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
/// The type of change the attribute underwent.
|
||||||
|
#[prost(enumeration = "ChangeType", tag = "3")]
|
||||||
|
pub change: i32,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct ProtocolType {
|
||||||
|
#[prost(string, tag = "1")]
|
||||||
|
pub name: ::prost::alloc::string::String,
|
||||||
|
#[prost(enumeration = "FinancialType", tag = "2")]
|
||||||
|
pub financial_type: i32,
|
||||||
|
#[prost(message, repeated, tag = "3")]
|
||||||
|
pub attribute_schema: ::prost::alloc::vec::Vec<Attribute>,
|
||||||
|
#[prost(enumeration = "ImplementationType", tag = "4")]
|
||||||
|
pub implementation_type: i32,
|
||||||
|
}
|
||||||
|
/// A struct describing a part of the protocol.
|
||||||
|
///
|
||||||
|
/// Note: For example this can be a UniswapV2 pair, that tracks the two ERC20 tokens used by the pair,
|
||||||
|
/// the component would represent a single contract. In case of VM integration, such component would
|
||||||
|
/// not need any attributes, because all the relevant info would be tracked via storage slots and balance changes.
|
||||||
|
/// It can also be a wrapping contract, like WETH, that has a constant price, but it allows swapping tokens.
|
||||||
|
/// This is why the name ProtocolComponent is used instead of "Pool" or "Pair".
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct ProtocolComponent {
|
||||||
|
/// A unique identifier for the component within the protocol.
|
||||||
|
/// Can be e.g. a stringified address or a string describing the trading pair.
|
||||||
|
#[prost(string, tag = "1")]
|
||||||
|
pub id: ::prost::alloc::string::String,
|
||||||
|
/// Addresses of the ERC20 tokens used by the component.
|
||||||
|
#[prost(bytes = "vec", repeated, tag = "2")]
|
||||||
|
pub tokens: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec<u8>>,
|
||||||
|
/// Addresses of the contracts used by the component.
|
||||||
|
/// Usually it is a single contract, but some protocols use multiple contracts.
|
||||||
|
#[prost(bytes = "vec", repeated, tag = "3")]
|
||||||
|
pub contracts: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec<u8>>,
|
||||||
|
/// Static attributes of the component.
|
||||||
|
/// These attributes MUST be immutable. If it can ever change, it should be given as an EntityChanges for this component id.
|
||||||
|
/// The inner ChangeType of the attribute has to match the ChangeType of the ProtocolComponent.
|
||||||
|
#[prost(message, repeated, tag = "4")]
|
||||||
|
pub static_att: ::prost::alloc::vec::Vec<Attribute>,
|
||||||
|
/// Type of change the component underwent.
|
||||||
|
#[prost(enumeration = "ChangeType", tag = "5")]
|
||||||
|
pub change: i32,
|
||||||
|
/// / Represents the functionality of the component.
|
||||||
|
#[prost(message, optional, tag = "6")]
|
||||||
|
pub protocol_type: ::core::option::Option<ProtocolType>,
|
||||||
|
/// Transaction where this component was created
|
||||||
|
#[prost(message, optional, tag = "7")]
|
||||||
|
pub tx: ::core::option::Option<Transaction>,
|
||||||
|
}
|
||||||
|
/// A struct for following the changes of Total Value Locked (TVL) of a protocol component.
|
||||||
|
///
|
||||||
|
/// Note that if a ProtocolComponent contains multiple contracts, the TVL is tracked for the component as a whole.
|
||||||
|
/// E.g. for UniswapV2 pair WETH/USDC, this tracks the USDC and WETH balance of the pair contract.
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct BalanceChange {
|
||||||
|
/// The address of the ERC20 token whose balance changed.
|
||||||
|
#[prost(bytes = "vec", tag = "1")]
|
||||||
|
pub token: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
/// The new balance of the token. Note: it must be a big endian encoded int.
|
||||||
|
#[prost(bytes = "vec", tag = "2")]
|
||||||
|
pub balance: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
/// The id of the component whose TVL is tracked. Note: This MUST be utf8 encoded.
|
||||||
|
/// If the protocol component includes multiple contracts, the balance change must be aggregated to reflect how much tokens can be traded.
|
||||||
|
#[prost(bytes = "vec", tag = "3")]
|
||||||
|
pub component_id: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
}
|
||||||
|
// Native entities
|
||||||
|
|
||||||
|
/// A component is a set of attributes that are associated with a custom entity.
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct EntityChanges {
|
||||||
|
/// A unique identifier of the entity within the protocol.
|
||||||
|
#[prost(string, tag = "1")]
|
||||||
|
pub component_id: ::prost::alloc::string::String,
|
||||||
|
/// The set of attributes that are associated with the entity.
|
||||||
|
#[prost(message, repeated, tag = "2")]
|
||||||
|
pub attributes: ::prost::alloc::vec::Vec<Attribute>,
|
||||||
|
}
|
||||||
|
// VM entities
|
||||||
|
|
||||||
|
/// A key value entry into contract storage.
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct ContractSlot {
|
||||||
|
/// A contract's storage slot.
|
||||||
|
#[prost(bytes = "vec", tag = "2")]
|
||||||
|
pub slot: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
/// The new value for this storage slot.
|
||||||
|
#[prost(bytes = "vec", tag = "3")]
|
||||||
|
pub value: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
}
|
||||||
|
/// Changes made to a single contract's state.
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct ContractChange {
|
||||||
|
/// The contract's address
|
||||||
|
#[prost(bytes = "vec", tag = "1")]
|
||||||
|
pub address: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
/// The new balance of the contract, empty bytes indicates no change.
|
||||||
|
#[prost(bytes = "vec", tag = "2")]
|
||||||
|
pub balance: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
/// The new code of the contract, empty bytes indicates no change.
|
||||||
|
#[prost(bytes = "vec", tag = "3")]
|
||||||
|
pub code: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
/// The changes to this contract's slots, empty sequence indicates no change.
|
||||||
|
#[prost(message, repeated, tag = "4")]
|
||||||
|
pub slots: ::prost::alloc::vec::Vec<ContractSlot>,
|
||||||
|
/// Whether this is an update, a creation or a deletion.
|
||||||
|
#[prost(enumeration = "ChangeType", tag = "5")]
|
||||||
|
pub change: i32,
|
||||||
|
}
|
||||||
|
// Aggregate entities
|
||||||
|
|
||||||
|
/// A set of changes aggregated by transaction.
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct TransactionChanges {
|
||||||
|
/// The transaction instance that results in the changes.
|
||||||
|
#[prost(message, optional, tag = "1")]
|
||||||
|
pub tx: ::core::option::Option<Transaction>,
|
||||||
|
/// Contains the changes induced by the above transaction, aggregated on a per-contract basis.
|
||||||
|
/// Contains the contract changes induced by the above transaction, usually for tracking VM components.
|
||||||
|
#[prost(message, repeated, tag = "2")]
|
||||||
|
pub contract_changes: ::prost::alloc::vec::Vec<ContractChange>,
|
||||||
|
/// Contains the entity changes induced by the above transaction.
|
||||||
|
/// Usually for tracking native components or used for VM extensions (plugins).
|
||||||
|
#[prost(message, repeated, tag = "3")]
|
||||||
|
pub entity_changes: ::prost::alloc::vec::Vec<EntityChanges>,
|
||||||
|
/// An array of newly added components.
|
||||||
|
#[prost(message, repeated, tag = "4")]
|
||||||
|
pub component_changes: ::prost::alloc::vec::Vec<ProtocolComponent>,
|
||||||
|
/// An array of balance changes to components.
|
||||||
|
#[prost(message, repeated, tag = "5")]
|
||||||
|
pub balance_changes: ::prost::alloc::vec::Vec<BalanceChange>,
|
||||||
|
}
|
||||||
|
/// A set of transaction changes within a single block.
|
||||||
|
/// This message must be the output of your substreams module.
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct BlockChanges {
|
||||||
|
/// The block for which these changes are collectively computed.
|
||||||
|
#[prost(message, optional, tag = "1")]
|
||||||
|
pub block: ::core::option::Option<Block>,
|
||||||
|
/// The set of transaction changes observed in the specified block.
|
||||||
|
#[prost(message, repeated, tag = "2")]
|
||||||
|
pub changes: ::prost::alloc::vec::Vec<TransactionChanges>,
|
||||||
|
}
|
||||||
|
/// Enum to specify the type of a change.
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
||||||
|
#[repr(i32)]
|
||||||
|
pub enum ChangeType {
|
||||||
|
Unspecified = 0,
|
||||||
|
Update = 1,
|
||||||
|
Creation = 2,
|
||||||
|
Deletion = 3,
|
||||||
|
}
|
||||||
|
impl ChangeType {
|
||||||
|
/// String value of the enum field names used in the ProtoBuf definition.
|
||||||
|
///
|
||||||
|
/// The values are not transformed in any way and thus are considered stable
|
||||||
|
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
|
||||||
|
pub fn as_str_name(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
ChangeType::Unspecified => "CHANGE_TYPE_UNSPECIFIED",
|
||||||
|
ChangeType::Update => "CHANGE_TYPE_UPDATE",
|
||||||
|
ChangeType::Creation => "CHANGE_TYPE_CREATION",
|
||||||
|
ChangeType::Deletion => "CHANGE_TYPE_DELETION",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||||
|
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
|
||||||
|
match value {
|
||||||
|
"CHANGE_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
|
||||||
|
"CHANGE_TYPE_UPDATE" => Some(Self::Update),
|
||||||
|
"CHANGE_TYPE_CREATION" => Some(Self::Creation),
|
||||||
|
"CHANGE_TYPE_DELETION" => Some(Self::Deletion),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
||||||
|
#[repr(i32)]
|
||||||
|
pub enum FinancialType {
|
||||||
|
Swap = 0,
|
||||||
|
Lend = 1,
|
||||||
|
Leverage = 2,
|
||||||
|
Psm = 3,
|
||||||
|
}
|
||||||
|
impl FinancialType {
|
||||||
|
/// String value of the enum field names used in the ProtoBuf definition.
|
||||||
|
///
|
||||||
|
/// The values are not transformed in any way and thus are considered stable
|
||||||
|
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
|
||||||
|
pub fn as_str_name(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
FinancialType::Swap => "SWAP",
|
||||||
|
FinancialType::Lend => "LEND",
|
||||||
|
FinancialType::Leverage => "LEVERAGE",
|
||||||
|
FinancialType::Psm => "PSM",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||||
|
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
|
||||||
|
match value {
|
||||||
|
"SWAP" => Some(Self::Swap),
|
||||||
|
"LEND" => Some(Self::Lend),
|
||||||
|
"LEVERAGE" => Some(Self::Leverage),
|
||||||
|
"PSM" => Some(Self::Psm),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
||||||
|
#[repr(i32)]
|
||||||
|
pub enum ImplementationType {
|
||||||
|
Vm = 0,
|
||||||
|
Custom = 1,
|
||||||
|
}
|
||||||
|
impl ImplementationType {
|
||||||
|
/// String value of the enum field names used in the ProtoBuf definition.
|
||||||
|
///
|
||||||
|
/// The values are not transformed in any way and thus are considered stable
|
||||||
|
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
|
||||||
|
pub fn as_str_name(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
ImplementationType::Vm => "VM",
|
||||||
|
ImplementationType::Custom => "CUSTOM",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||||
|
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
|
||||||
|
match value {
|
||||||
|
"VM" => Some(Self::Vm),
|
||||||
|
"CUSTOM" => Some(Self::Custom),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A message containing relative balance changes.
|
||||||
|
///
|
||||||
|
/// Used to track token balances of protocol components in case they are only
|
||||||
|
/// available as relative values within a block.
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct BalanceDelta {
|
||||||
|
/// The ordinal of the balance change. Must be unique & deterministic over all balances
|
||||||
|
/// changes within a block.
|
||||||
|
#[prost(uint64, tag = "1")]
|
||||||
|
pub ord: u64,
|
||||||
|
/// The tx hash of the transaction that caused the balance change.
|
||||||
|
#[prost(message, optional, tag = "2")]
|
||||||
|
pub tx: ::core::option::Option<Transaction>,
|
||||||
|
/// The address of the ERC20 token whose balance changed.
|
||||||
|
#[prost(bytes = "vec", tag = "3")]
|
||||||
|
pub token: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
/// The delta balance of the token.
|
||||||
|
#[prost(bytes = "vec", tag = "4")]
|
||||||
|
pub delta: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
/// The id of the component whose TVL is tracked.
|
||||||
|
/// If the protocol component includes multiple contracts, the balance change must be
|
||||||
|
/// aggregated to reflect how much tokens can be traded.
|
||||||
|
#[prost(bytes = "vec", tag = "5")]
|
||||||
|
pub component_id: ::prost::alloc::vec::Vec<u8>,
|
||||||
|
}
|
||||||
|
/// A set of balances deltas, usually a group of changes within a single block.
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct BlockBalanceDeltas {
|
||||||
|
#[prost(message, repeated, tag = "1")]
|
||||||
|
pub balance_deltas: ::prost::alloc::vec::Vec<BalanceDelta>,
|
||||||
|
}
|
||||||
|
/// A message containing protocol components that were created by a single tx.
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct TransactionProtocolComponents {
|
||||||
|
#[prost(message, optional, tag = "1")]
|
||||||
|
pub tx: ::core::option::Option<Transaction>,
|
||||||
|
#[prost(message, repeated, tag = "2")]
|
||||||
|
pub components: ::prost::alloc::vec::Vec<ProtocolComponent>,
|
||||||
|
}
|
||||||
|
/// All protocol components that were created within a block with their corresponding tx.
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct BlockTransactionProtocolComponents {
|
||||||
|
#[prost(message, repeated, tag = "1")]
|
||||||
|
pub tx_components: ::prost::alloc::vec::Vec<TransactionProtocolComponents>,
|
||||||
|
}
|
||||||
|
// @@protoc_insertion_point(module)
|
||||||
71
substreams/ethereum-sfrax/substreams.yaml
Normal file
71
substreams/ethereum-sfrax/substreams.yaml
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
specVersion: v0.1.0
|
||||||
|
package:
|
||||||
|
name: "ethereum_sfrax"
|
||||||
|
version: v0.1.0
|
||||||
|
|
||||||
|
protobuf:
|
||||||
|
files:
|
||||||
|
- tycho/evm/v1/vm.proto
|
||||||
|
- tycho/evm/v1/common.proto
|
||||||
|
- tycho/evm/v1/utils.proto
|
||||||
|
importPaths:
|
||||||
|
- ../../proto
|
||||||
|
- ./proto
|
||||||
|
|
||||||
|
binaries:
|
||||||
|
default:
|
||||||
|
type: wasm/rust-v1
|
||||||
|
file: ../target/wasm32-unknown-unknown/release/ethereum_sfrax.wasm
|
||||||
|
|
||||||
|
modules:
|
||||||
|
- name: map_components
|
||||||
|
kind: map
|
||||||
|
initialBlock: 18378085
|
||||||
|
inputs:
|
||||||
|
- params: string
|
||||||
|
- source: sf.ethereum.type.v2.Block
|
||||||
|
output:
|
||||||
|
type: proto:tycho.evm.v1.BlockTransactionProtocolComponents
|
||||||
|
doc: |
|
||||||
|
param is the address without the 0x prefix of the sfrax vault you want to track
|
||||||
|
|
||||||
|
- name: store_components
|
||||||
|
kind: store
|
||||||
|
initialBlock: 18378085
|
||||||
|
updatePolicy: add
|
||||||
|
valueType: int64
|
||||||
|
inputs:
|
||||||
|
- map: map_components
|
||||||
|
|
||||||
|
- name: store_balances
|
||||||
|
kind: store
|
||||||
|
initialBlock: 18378085
|
||||||
|
updatePolicy: add
|
||||||
|
valueType: bigint
|
||||||
|
inputs:
|
||||||
|
- map: map_relative_balances
|
||||||
|
|
||||||
|
- name: map_relative_balances
|
||||||
|
kind: map
|
||||||
|
initialBlock: 18378085
|
||||||
|
inputs:
|
||||||
|
- source: sf.ethereum.type.v2.Block
|
||||||
|
- store: store_components
|
||||||
|
output:
|
||||||
|
type: proto:tycho.evm.v1.BlockBalanceDeltas
|
||||||
|
|
||||||
|
- name: map_protocol_changes
|
||||||
|
kind: map
|
||||||
|
initialBlock: 18378085
|
||||||
|
inputs:
|
||||||
|
- source: sf.ethereum.type.v2.Block
|
||||||
|
- map: map_components
|
||||||
|
- map: map_relative_balances
|
||||||
|
- store: store_components
|
||||||
|
- store: store_balances
|
||||||
|
mode: deltas
|
||||||
|
output:
|
||||||
|
type: proto:tycho.evm.v1.BlockChanges
|
||||||
|
|
||||||
|
params:
|
||||||
|
map_components: "A663B02CF0a4b149d2aD41910CB81e23e1c41c32"
|
||||||
Reference in New Issue
Block a user