hoodquidity/packages/contracts/lib/openzeppelin-contracts/test/utils/SimulatedCall.test.js
Денис Зефиров dba2811447 Hoodquidity: liquidity campaigns for Robinhood Chain stock token markets
Full build: Vite/React acid-terminal frontend (BEARER design system,
Panchang/Sentient/Fragment Mono, neon layer, palette audit script),
HoodquidityVaults Foundry contracts (single+dual deposits via Chainlink-style
feeds, hybrid exit, 10% platform fee, boost, Genesis LP), Reown AppKit wallet
connect with Robinhood Chain testnet (46630), live data from Dexscreener and
onchain reads, partner portal, design-sync setup for claude.ai/design.

Deploy: static via Forgejo Actions platform, BUILD_DIR=apps/web/dist (.env).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 08:32:28 +04:00

101 lines
4 KiB
JavaScript

const { ethers } = require('hardhat');
const { expect } = require('chai');
const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers');
const value = 42n;
async function fixture() {
const [receiver, other] = await ethers.getSigners();
const mock = await ethers.deployContract('$SimulateCall');
const simulator = ethers.getCreate2Address(
mock.target,
ethers.ZeroHash,
ethers.keccak256(
ethers.concat([
'0x60315f8160095f39f3',
'0x60333611600a575f5ffd5b6034360360345f375f5f603436035f6014355f3560601c5af13d5f5f3e5f3d91602f57f35bfd',
]),
),
);
const target = await ethers.deployContract('$CallReceiverMock');
// fund the mock contract (for tests that use value)
await other.sendTransaction({ to: mock, value });
return { mock, target, receiver, other, simulator };
}
describe('SimulateCall', function () {
beforeEach(async function () {
Object.assign(this, await loadFixture(fixture));
});
it('automatic simulator deployment', async function () {
await expect(ethers.provider.getCode(this.simulator)).to.eventually.equal('0x');
// First call performs deployment
await expect(this.mock.$getSimulator()).to.emit(this.mock, 'return$getSimulator').withArgs(this.simulator);
await expect(ethers.provider.getCode(this.simulator)).to.eventually.not.equal('0x');
// Following calls use the same simulator
await expect(this.mock.$getSimulator()).to.emit(this.mock, 'return$getSimulator').withArgs(this.simulator);
});
describe('simulated call', function () {
it('target success', async function () {
const txPromise = this.mock.$simulateCall(
ethers.Typed.address(this.target),
ethers.Typed.bytes(this.target.interface.encodeFunctionData('mockFunctionWithArgsReturn', [10, 20])),
);
await expect(txPromise).to.changeEtherBalances([this.mock, this.simulator, this.target], [0n, 0n, 0n]);
await expect(txPromise)
.to.emit(this.mock, 'return$simulateCall_address_bytes')
.withArgs(true, ethers.AbiCoder.defaultAbiCoder().encode(['uint256', 'uint256'], [10, 20]))
.to.not.emit(this.target, 'MockFunctionCalledWithArgs');
});
it('target success (with value)', async function () {
// perform simulated call
const txPromise = this.mock.$simulateCall(
ethers.Typed.address(this.target),
ethers.Typed.uint256(value),
ethers.Typed.bytes(this.target.interface.encodeFunctionData('mockFunctionExtra')),
);
await expect(txPromise).to.changeEtherBalances([this.mock, this.simulator, this.target], [0n, 0n, 0n]);
await expect(txPromise)
.to.emit(this.mock, 'return$simulateCall_address_uint256_bytes')
.withArgs(true, ethers.AbiCoder.defaultAbiCoder().encode(['address', 'uint256'], [this.mock.target, value]))
.to.not.emit(this.target, 'MockFunctionCalledExtra');
});
it('target revert', async function () {
const txPromise = this.mock.$simulateCall(
ethers.Typed.address(this.target),
ethers.Typed.bytes(this.target.interface.encodeFunctionData('mockFunctionRevertsReason')),
);
await expect(txPromise).to.changeEtherBalances([this.mock, this.simulator, this.target], [0n, 0n, 0n]);
await expect(txPromise)
.to.emit(this.mock, 'return$simulateCall_address_bytes')
.withArgs(false, this.target.interface.encodeErrorResult('Error', ['CallReceiverMock: reverting']));
});
it('target revert (with value)', async function () {
const txPromise = this.mock.$simulateCall(
ethers.Typed.address(this.target),
ethers.Typed.uint256(value),
ethers.Typed.bytes(this.target.interface.encodeFunctionData('mockFunctionRevertsReason')),
);
await expect(txPromise).to.changeEtherBalances([this.mock, this.simulator, this.target], [0n, 0n, 0n]);
await expect(txPromise)
.to.emit(this.mock, 'return$simulateCall_address_uint256_bytes')
.withArgs(false, this.target.interface.encodeErrorResult('Error', ['CallReceiverMock: reverting']));
});
});
});