I have two interacting smart contracts that I am developing/testing in Hardhat and deploying to RSK:
DelegateCalleesmart contract with agetData()function, emitting aReceivedevent:
contract DelegateCallee {
event Received(address sender, uint value);
function getData() external payable {
emit Received(msg.sender, msg.value);
}
}
DelegateCallersmart contract which uses Solidity'sdelegateCallto invokegetData()from theDelegateCallee:
contract DelegateCaller {
address callee;
constructor(address _callee) {
callee = _callee;
}
function delegateCallGetData() external payable {
(bool success, ) = callee.delegatecall(
abi.encodeWithSelector(DelegateCallee.getData.selector)
);
require(success, "delegate call failed");
}
}
I am running Hardhat tests to intercept the events emitted by DelegateCallee. When I am invoking getData() directly on the DelegateCallee, the event is being emitted as expected:
it('getData function on callee should emit the Received event', async () => {
const value = ethers.utils.parseEther('1');
const tx = await delagateCallee.getData({ value });
await expect(tx)
.to.emit(delagateCallee, 'Received')
.withArgs(deployer.address, value);
});
Low level calls
✔ getData function on callee should emit the Received event
However when I use the DelegateCaller contract,
invoking its delegateCallGetData(),
which in turn invokes the DelegateCallee contract's
getData() function, the Received event is not emitted.
it('delegateCallGetData function on caller should emit the Received event on the callee', async () => {
const value = ethers.utils.parseEther('1');
const tx = await delegateCaller.delegateCallGetData({ value });
await expect(tx)
.to.emit(delagateCallee, 'Received')
.withArgs(deployer.address, value);
});
1) Low level calls
delegateCallGetData function on caller should emit the Received event on the callee:
AssertionError: Expected event "Received" to be emitted, but it wasn't
Where is my event lost?
Most likely, the
Receivedevent is there, though Hardhat doesn't recognise it as aDelegateCalleeevent. This happens because you are invoking the function viadelegateCall. Waffle/ Hardhat expects the event emitter to be theDelegateCalleesmart contract, but due to the fact that the function was called in the context of another smart contract, theDelegateCallerwas probably registered as an emitter. To make sure, you should try the following:interface.decodeEventLog()(from ethers.js) to decode this event's parameters