@atomiqlabs/chain-evm
Version:
EVM specific base implementation
78 lines (66 loc) • 4.63 kB
text/typescript
import {EVMSpvVaultContract} from "../../evm/spv_swap/EVMSpvVaultContract";
import {EVMSpvWithdrawalData} from "../../evm/spv_swap/EVMSpvWithdrawalData";
import {EVMSpvVaultData} from "../../evm/spv_swap/EVMSpvVaultData";
import {ZeroAddress, ZeroHash} from "ethers";
import {CitreaFees} from "./CitreaFees";
import {EVMAddresses} from "../../evm/chain/modules/EVMAddresses";
export class CitreaSpvVaultContract extends EVMSpvVaultContract<"CITREA"> {
public static readonly StateDiffSize = {
BASE_DIFF_SIZE: 50,
ERC_20_TRANSFER_DIFF_SIZE: 50,
NATIVE_SELF_TRANSFER_DIFF_SIZE: 20,
NATIVE_TRANSFER_DIFF_SIZE: 55,
EXECUTION_SCHEDULE_DIFF_SIZE: 40
};
private calculateStateDiff(signer: string, tokenStateChanges: Set<string>): number {
let stateDiffSize = 0;
tokenStateChanges.forEach(val => {
const [address, token] = val.split(":");
if(token.toLowerCase()===this.Chain.getNativeCurrencyAddress().toLowerCase()) {
stateDiffSize += address.toLowerCase()===signer?.toLowerCase() ? CitreaSpvVaultContract.StateDiffSize.NATIVE_SELF_TRANSFER_DIFF_SIZE : CitreaSpvVaultContract.StateDiffSize.NATIVE_TRANSFER_DIFF_SIZE;
} else {
stateDiffSize += CitreaSpvVaultContract.StateDiffSize.ERC_20_TRANSFER_DIFF_SIZE;
}
});
return stateDiffSize;
}
async getClaimFee(signer: string, vault?: EVMSpvVaultData, data?: EVMSpvWithdrawalData, feeRate?: string): Promise<bigint> {
vault ??= EVMSpvVaultData.randomVault();
feeRate ??= await this.Chain.Fees.getFeeRate();
const tokenStateChanges: Set<string> = new Set();
let diffSize = CitreaSpvVaultContract.StateDiffSize.BASE_DIFF_SIZE;
const recipient = data!=null ? data.recipient : EVMAddresses.randomAddress();
if (data==null || (data.rawAmounts[0] != null && data.rawAmounts[0] > 0n)) {
const token0Address = vault==null ? EVMAddresses.randomAddress().toLowerCase() : vault.token0.token.toLowerCase();
tokenStateChanges.add(recipient.toLowerCase()+":"+token0Address);
if (data==null || data.frontingFeeRate > 0n) tokenStateChanges.add(ZeroAddress+":"+token0Address); //Also needs to pay out to fronter
if (data==null || data.callerFeeRate > 0n) tokenStateChanges.add(signer+":"+token0Address); //Also needs to pay out to caller
}
if (data==null || (data.rawAmounts[1] != null && data.rawAmounts[1] > 0n)) {
const token1Address = vault==null ? this.Chain.getNativeCurrencyAddress().toLowerCase() : vault.token1.token.toLowerCase();
tokenStateChanges.add(recipient.toLowerCase()+":"+token1Address);
if (data==null || data.frontingFeeRate > 0n) tokenStateChanges.add(ZeroAddress+":"+token1Address); //Also needs to pay out to fronter
if (data==null || data.callerFeeRate > 0n) tokenStateChanges.add(signer+":"+token1Address); //Also needs to pay out to caller
}
diffSize += this.calculateStateDiff(signer, tokenStateChanges);
if (data==null || (data.executionHash != null && data.executionHash !== ZeroHash)) diffSize += CitreaSpvVaultContract.StateDiffSize.EXECUTION_SCHEDULE_DIFF_SIZE;
const gasFee = await super.getClaimFee(signer, vault, data, feeRate);
return gasFee + CitreaFees.getGasFee(0, feeRate, diffSize);
}
async getFrontFee(signer: string, vault?: EVMSpvVaultData, data?: EVMSpvWithdrawalData, feeRate?: string): Promise<bigint> {
vault ??= EVMSpvVaultData.randomVault();
feeRate ??= await this.Chain.Fees.getFeeRate();
const tokenStateChanges: Set<string> = new Set();
let diffSize = CitreaSpvVaultContract.StateDiffSize.BASE_DIFF_SIZE;
if (data==null || (data.rawAmounts[0] != null && data.rawAmounts[0] > 0n)) {
tokenStateChanges.add(signer+":"+vault.token0.token.toLowerCase());
}
if (data==null || (data.rawAmounts[1] != null && data.rawAmounts[1] > 0n)) {
tokenStateChanges.add(signer+":"+vault.token1.token.toLowerCase());
}
diffSize += this.calculateStateDiff(signer, tokenStateChanges);
if (data==null || (data.executionHash != null && data.executionHash !== ZeroHash)) diffSize += CitreaSpvVaultContract.StateDiffSize.EXECUTION_SCHEDULE_DIFF_SIZE;
const gasFee = await super.getFrontFee(signer, vault, data, feeRate);
return gasFee + CitreaFees.getGasFee(0, feeRate, diffSize);
}
}