UNPKG

ethers-override

Version:
43 lines (42 loc) 1.9 kB
import { keccak256, solidityPacked, toBeHex, zeroPadValue } from "ethers"; import { AddressAsIf } from "./addressAsIf.js"; // import { abi as permit2Abi } from '../abi/permit2.json' // const permit2Interface: Interface = new Interface(permit2Abi); const getAllowanceSlotKey = (ownerAddress, tokenAddress, spenderAddress, mappingSlotNumber) => { return keccak256(zeroPadValue(spenderAddress, 32) + keccak256(zeroPadValue(tokenAddress, 32) + keccak256(zeroPadValue(ownerAddress, 32) + toBeHex(mappingSlotNumber, 32).slice(2)).slice(2)).slice(2)); }; export class Permit2AsIf extends AddressAsIf { constructor(address) { super(address); this._method = undefined; this._allowanceMappingSlotNumber = 1; } allowance(ownerAddress, tokenAddress, spenderAddress) { this._method = "allowance"; super.stateDiff(getAllowanceSlotKey(ownerAddress, tokenAddress, spenderAddress, this._allowanceMappingSlotNumber)); return this; } is(value) { if (this._method === undefined) { throw new Error(`Method to call of AsIf at ${this.address} is not set!`); } if (this._method === "allowance") { if (value === undefined || typeof value.amount !== 'bigint' || typeof value.expiration !== 'bigint' || typeof value.nonce !== 'bigint') { throw new Error(`Invalid value for ${this._method} of Permit2AsIf.`); } const slotValue = solidityPacked(["uint48", "uint48", "uint160"], [value.nonce, value.expiration, value.amount]); super.is(slotValue); } return this; } } ; const PERMIT2_ADDRESS = "0x000000000022d473030f116ddee9f6b43ac78ba3"; export const permit2 = new Permit2AsIf(PERMIT2_ADDRESS); export const exportedForTesting = { getAllowanceSlotKey };