@d3or/slotseek
Version:
A library for finding the storage slots on an ERC20 token for balances and approvals, which can be used to mock the balances and approvals of an address when estimating gas costs of transactions that would fail if the address did not have the required bal
43 lines • 2.52 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.getPermit2ERC20Allowance = exports.computePermit2AllowanceStorageSlot = void 0;
const ethers_1 = require("ethers");
/**
* Compute the storage slot for permit2 allowance.
* NOTE: unlike arbitrary erc20 contracts, we know the slot for where this is stored (1) :)
*
* @param erc20Address - The address of the ERC20 token
* @param ownerAddress - The address of the ERC20 token owner
* @param spenderAddress - The address of the spender
* @returns The slot where the allowance amount is stored, mock this
*
* - This uses a brute force approach similar to the balance slot search. See the balance slot search comment for more details.
*/
const computePermit2AllowanceStorageSlot = (ownerAddress, erc20Address, spenderAddress) => {
// Calculate the slot hash, using the owner address and the slot index (1)
const ownerSlotHash = ethers_1.ethers.utils.keccak256(ethers_1.ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [ownerAddress, 1]));
// Calcualte the storage slot hash for spender slot
const tokenSlotHash = ethers_1.ethers.utils.keccak256(ethers_1.ethers.utils.defaultAbiCoder.encode(["address", "bytes32"], [erc20Address, ownerSlotHash]));
// Calculate the final storage slot to mock, using the spender address and the slot hash2
const slot = ethers_1.ethers.utils.keccak256(ethers_1.ethers.utils.defaultAbiCoder.encode(["address", "bytes32"], [spenderAddress, tokenSlotHash]));
return { slot };
};
exports.computePermit2AllowanceStorageSlot = computePermit2AllowanceStorageSlot;
/**
* Get the permit2 erc20 allowance for a given ERC20 token and spender
* @param provider - The JsonRpcProvider instance
* @param permit2Address - The permit2 contract address
* @param erc20Address - The address of the ERC20 token
* @param ownerAddress - The address of the ERC20 token owner
* @param spenderAddress - The address of the spender
* @returns The approval amount
*/
const getPermit2ERC20Allowance = async (provider, permit2Address, ownerAddress, erc20Address, spenderAddress) => {
const contract = new ethers_1.ethers.Contract(permit2Address, [
"function allowance(address owner, address token, address spender) view returns (uint256)",
], provider);
const approval = await contract.allowance(ownerAddress, erc20Address, spenderAddress);
return approval;
};
exports.getPermit2ERC20Allowance = getPermit2ERC20Allowance;
//# sourceMappingURL=permit2.js.map
;