Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve(InventoryClient): Align allocation percentage computations between Rebalancer and Relayer #1523

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
14 changes: 7 additions & 7 deletions src/clients/InventoryClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,6 @@ export class InventoryClient {
const chainShortfall = this.tokenClient.getShortfallTotalRequirement(_chain, repaymentToken);
const chainVirtualBalance = this.getBalanceOnChain(_chain, l1Token, repaymentToken);
const chainVirtualBalanceWithShortfall = chainVirtualBalance.sub(chainShortfall);
let cumulativeVirtualBalanceWithShortfall = cumulativeVirtualBalance.sub(chainShortfall);
// @dev No need to factor in outputAmount when computing origin chain balance since funds only leave relayer
// on destination chain
// @dev Do not subtract outputAmount from virtual balance if output token and input token are not equivalent.
Expand All @@ -496,14 +495,13 @@ export class InventoryClient {
);
// To correctly compute the allocation % for this destination chain, we need to add all upcoming refunds for the
// equivalents of l1Token on all chains.
cumulativeVirtualBalanceWithShortfall = cumulativeVirtualBalanceWithShortfall.add(cumulativeRefunds);
const cumulativeVirtualBalanceWithShortfallPostRelay = cumulativeVirtualBalanceWithShortfall.sub(outputAmount);
const cumulativeVirtualBalancePostRelay = cumulativeVirtualBalance.add(cumulativeRefunds).sub(outputAmount);

// Compute what the balance will be on the target chain, considering this relay and the finalization of the
// transfers that are currently flowing through the canonical bridge.
const expectedPostRelayAllocation = chainVirtualBalanceWithShortfallPostRelay
.mul(this.scalar)
.div(cumulativeVirtualBalanceWithShortfallPostRelay);
.div(cumulativeVirtualBalancePostRelay);
nicholaspai marked this conversation as resolved.
Show resolved Hide resolved

// Consider configured buffer for target to allow relayer to support slight overages.
const tokenConfig = this.getTokenConfig(l1Token, _chain, repaymentToken);
Expand All @@ -527,8 +525,7 @@ export class InventoryClient {
chainVirtualBalanceWithShortfall,
chainVirtualBalanceWithShortfallPostRelay,
cumulativeVirtualBalance,
cumulativeVirtualBalanceWithShortfall,
cumulativeVirtualBalanceWithShortfallPostRelay,
cumulativeVirtualBalancePostRelay,
thresholdPct,
expectedPostRelayAllocation,
chainsToEvaluate,
Expand Down Expand Up @@ -869,7 +866,10 @@ export class InventoryClient {
this.crossChainTransferClient
.getOutstandingCrossChainTransferAmount(this.relayer, chainId, l1Token, l2Token)
.toString()
)}.\n`;
)}.` +
` This chain has a shortfall of ${formatter(
this.tokenClient.getShortfallTotalRequirement(chainId, l2Token).toString()
)} ${symbol}.\n`;
}
}

Expand Down
21 changes: 9 additions & 12 deletions test/InventoryClient.RefundChain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,11 +202,10 @@ describe("InventoryClient: Refund chain selection", async function () {
// 3. chainVirtualBalanceWithShortfallPostRelay: virtual balance with shortfall minus the relay amount. 9.8-1.69=8.11.
// 4. cumulativeVirtualBalance: total balance across all chains considering fund movement. funds moving over the bridge
// does not impact the balance; they are just "moving" so it should be 140-15+15=140
// 5. cumulativeVirtualBalanceWithShortfall: cumulative virtual balance minus the shortfall. 140-15+15=140-15=125.
// 6. cumulativeVirtualBalanceWithShortfallPostRelay: cumulative virtual balance with shortfall minus the relay amount
// 125-1.69=124.31. This is total funds considering the shortfall and the relay amount that is to be executed.
// 7. expectedPostRelayAllocation: the expected post relay allocation is the chainVirtualBalanceWithShortfallPostRelay
// divided by the cumulativeVirtualBalanceWithShortfallPostRelay. 8.11/123.31 = 0.0657.
// 5. cumulativeVirtualBalancePostRelay: cumulative virtual balance plus upcoming refunds minus the relay amount
// 140-1.69=138.31. This is total funds considering the relay amount that is to be executed.
// 6. expectedPostRelayAllocation: the expected post relay allocation is the chainVirtualBalanceWithShortfallPostRelay
// divided by the cumulativeVirtualBalancePostRelay. 8.11/138.31 = 0.0586.
// This number is then used to decide on where funds should be allocated! If this number is above the threshold plus
// the buffer then refund on L1. if it is below the threshold then refund on the target chain. As this number is
// is below the buffer plus the threshold then the bot should refund on L2.
Expand All @@ -222,20 +221,18 @@ describe("InventoryClient: Refund chain selection", async function () {
expect(lastSpyLogIncludes(spy, 'chainVirtualBalanceWithShortfall":"9800000000000000000"')).to.be.true; // 24.8-15=9.8
expect(lastSpyLogIncludes(spy, 'chainVirtualBalanceWithShortfallPostRelay":"8110000000000000000"')).to.be.true; // 9.8-1.69=8.11
expect(lastSpyLogIncludes(spy, 'cumulativeVirtualBalance":"140000000000000000000')).to.be.true; // 140-15+15=140
expect(lastSpyLogIncludes(spy, 'cumulativeVirtualBalanceWithShortfall":"125000000000000000000"')).to.be.true; // 140-15=125
expect(lastSpyLogIncludes(spy, 'cumulativeVirtualBalanceWithShortfallPostRelay":"123310000000000000000"')).to.be
.true; // 125-1.69=123.31
expect(lastSpyLogIncludes(spy, 'expectedPostRelayAllocation":"65769199578298597')).to.be.true; // 8.11/123.31 = 0.0657
expect(lastSpyLogIncludes(spy, 'cumulativeVirtualBalancePostRelay":"138310000000000000000"')).to.be.true; // 125-1.69=123.31
expect(lastSpyLogIncludes(spy, 'expectedPostRelayAllocation":"58636396500614561')).to.be.true; // 8.11/123.31 = 0.0657

// Now consider if this small relay was larger to the point that we should be refunding on the L2. set it to 5 WETH.
// Numerically we can shortcut some of the computations above to the following: chain virtual balance with shortfall
// post relay is 9.8 - 5 = 4.8. cumulative virtual balance with shortfall post relay is 125 - 5 = 120. Expected post
// relay allocation is 4.8/120 = 0.04. This is below the threshold of 0.05 so the bot should refund on the target.
// post relay is 9.8 - 5 = 4.8. cumulative virtual balance post relay is 140 - 5 = 135. Expected post
// relay allocation is 4.8/135 = 0.036. This is below the threshold of 0.05 so the bot should refund on the target.
sampleDepositData.inputAmount = toWei(5);
sampleDepositData.outputAmount = await computeOutputAmount(sampleDepositData);
expect(await inventoryClient.determineRefundChainId(sampleDepositData)).to.equal(ARBITRUM);
// Check only the final step in the computation.
expect(lastSpyLogIncludes(spy, 'expectedPostRelayAllocation":"40000000000000000"')).to.be.true; // 4.8/120 = 0.04
expect(lastSpyLogIncludes(spy, 'expectedPostRelayAllocation":"35555555555555555"')).to.be.true; // 4.8/120 = 0.04

// Consider that we manually send the relayer som funds while it's large transfer is currently in the bridge. This
// is to validate that the module considers funds in transit correctly + dropping funds indirectly onto the L2 wallet.
Expand Down
Loading