230 lines
7.9 KiB
Solidity
230 lines
7.9 KiB
Solidity
// SPDX-License-Identifier: Apache 2
|
|
|
|
pragma solidity ^0.8.0;
|
|
|
|
import "../contracts/interfaces/IRelayProvider.sol";
|
|
import "../contracts/relayProvider/RelayProvider.sol";
|
|
import "../contracts/relayProvider/RelayProviderSetup.sol";
|
|
import "../contracts/relayProvider/RelayProviderImplementation.sol";
|
|
import "../contracts/relayProvider/RelayProviderProxy.sol";
|
|
import "../contracts/relayProvider/RelayProviderMessages.sol";
|
|
import "../contracts/relayProvider/RelayProviderStructs.sol";
|
|
|
|
import "forge-std/Test.sol";
|
|
|
|
contract TestRelayProvider is Test {
|
|
uint16 constant TEST_ORACLE_CHAIN_ID = 2;
|
|
|
|
RelayProvider internal relayProvider;
|
|
|
|
function initializeRelayProvider() internal {
|
|
RelayProviderSetup relayProviderSetup = new RelayProviderSetup();
|
|
RelayProviderImplementation relayProviderImplementation = new RelayProviderImplementation();
|
|
RelayProviderProxy myRelayProvider = new RelayProviderProxy(
|
|
address(relayProviderSetup),
|
|
abi.encodeWithSelector(
|
|
bytes4(keccak256("setup(address,uint16)")),
|
|
address(relayProviderImplementation),
|
|
TEST_ORACLE_CHAIN_ID
|
|
)
|
|
);
|
|
|
|
relayProvider = RelayProvider(address(myRelayProvider));
|
|
|
|
require(relayProvider.owner() == address(this), "owner() != expected");
|
|
require(relayProvider.chainId() == TEST_ORACLE_CHAIN_ID, "chainId() != expected");
|
|
}
|
|
|
|
function testCannotUpdatePriceWithChainIdZero(uint128 updateGasPrice, uint128 updateNativeCurrencyPrice) public {
|
|
vm.assume(updateGasPrice > 0);
|
|
vm.assume(updateNativeCurrencyPrice > 0);
|
|
|
|
initializeRelayProvider();
|
|
|
|
// you shall not pass
|
|
vm.expectRevert(abi.encodeWithSignature("ChainIdIsZero()"));
|
|
relayProvider.updatePrice(
|
|
0, // updateChainId
|
|
updateGasPrice,
|
|
updateNativeCurrencyPrice
|
|
);
|
|
}
|
|
|
|
function testCannotUpdatePriceWithGasPriceZero(uint16 updateChainId, uint128 updateNativeCurrencyPrice) public {
|
|
vm.assume(updateChainId > 0);
|
|
vm.assume(updateNativeCurrencyPrice > 0);
|
|
|
|
initializeRelayProvider();
|
|
|
|
// you shall not pass
|
|
vm.expectRevert(abi.encodeWithSignature("GasPriceIsZero()"));
|
|
relayProvider.updatePrice(
|
|
updateChainId,
|
|
0, // updateGasPrice == 0
|
|
updateNativeCurrencyPrice
|
|
);
|
|
}
|
|
|
|
function testCannotUpdatePriceWithNativeCurrencyPriceZero(uint16 updateChainId, uint128 updateGasPrice) public {
|
|
vm.assume(updateChainId > 0);
|
|
vm.assume(updateGasPrice > 0);
|
|
|
|
initializeRelayProvider();
|
|
|
|
// you shall not pass
|
|
vm.expectRevert(abi.encodeWithSignature("NativeCurrencyPriceIsZero()"));
|
|
relayProvider.updatePrice(
|
|
updateChainId,
|
|
updateGasPrice,
|
|
0 // updateNativeCurrencyPrice == 0
|
|
);
|
|
}
|
|
|
|
function testCanUpdatePriceOnlyAsOwner(
|
|
address oracleOwner,
|
|
uint16 updateChainId,
|
|
uint128 updateGasPrice,
|
|
uint128 updateNativeCurrencyPrice
|
|
) public {
|
|
vm.assume(oracleOwner != address(0));
|
|
vm.assume(oracleOwner != address(this));
|
|
vm.assume(updateChainId > 0);
|
|
vm.assume(updateGasPrice > 0);
|
|
vm.assume(updateNativeCurrencyPrice > 0);
|
|
|
|
initializeRelayProvider();
|
|
|
|
// you shall not pass
|
|
vm.prank(oracleOwner);
|
|
vm.expectRevert(abi.encodeWithSignature("CallerMustBeOwner()"));
|
|
relayProvider.updatePrice(updateChainId, updateGasPrice, updateNativeCurrencyPrice);
|
|
}
|
|
|
|
/*
|
|
TODO: Uncomment these tests once revert messages are back in
|
|
function testCannotGetPriceBeforeUpdateSrcPrice(
|
|
uint16 dstChainId,
|
|
uint128 dstGasPrice,
|
|
uint128 dstNativeCurrencyPrice
|
|
)
|
|
public
|
|
{
|
|
vm.assume(dstChainId > 0);
|
|
vm.assume(dstChainId != TEST_ORACLE_CHAIN_ID);
|
|
vm.assume(dstGasPrice > 0);
|
|
vm.assume(dstNativeCurrencyPrice > 0);
|
|
|
|
initializeRelayProvider();
|
|
|
|
// update the price with reasonable values
|
|
relayProvider.updatePrice(dstChainId, dstGasPrice, dstNativeCurrencyPrice);
|
|
|
|
// you shall not pass
|
|
vm.expectRevert("srcNativeCurrencyPrice == 0");
|
|
relayProvider.quoteDeliveryOverhead(dstChainId);
|
|
}
|
|
|
|
function testCannotGetPriceBeforeUpdateDstPrice(
|
|
uint16 dstChainId,
|
|
uint128 srcGasPrice,
|
|
uint128 srcNativeCurrencyPrice
|
|
)
|
|
public
|
|
{
|
|
vm.assume(dstChainId > 0);
|
|
vm.assume(dstChainId != TEST_ORACLE_CHAIN_ID);
|
|
vm.assume(srcGasPrice > 0);
|
|
vm.assume(srcNativeCurrencyPrice > 0);
|
|
|
|
initializeRelayProvider();
|
|
|
|
// update the price with reasonable values
|
|
//vm.prank(relayProvider.owner());
|
|
relayProvider.updatePrice(TEST_ORACLE_CHAIN_ID, srcGasPrice, srcNativeCurrencyPrice);
|
|
|
|
// you shall not pass
|
|
vm.expectRevert("dstNativeCurrencyPrice == 0");
|
|
relayProvider.quoteDeliveryOverhead(dstChainId);
|
|
}
|
|
*/
|
|
|
|
function testUpdatePrice(
|
|
uint16 dstChainId,
|
|
uint128 dstGasPrice,
|
|
uint64 dstNativeCurrencyPrice,
|
|
uint128 srcGasPrice,
|
|
uint64 srcNativeCurrencyPrice,
|
|
uint32 gasLimit,
|
|
uint32 deliverGasOverhead,
|
|
uint32 targetWormholeFee
|
|
) public {
|
|
vm.assume(dstChainId > 0);
|
|
vm.assume(dstChainId != TEST_ORACLE_CHAIN_ID);
|
|
vm.assume(dstGasPrice > 0);
|
|
vm.assume(dstNativeCurrencyPrice > 0);
|
|
vm.assume(srcGasPrice > 0);
|
|
vm.assume(srcNativeCurrencyPrice > 0);
|
|
vm.assume(uint256(dstGasPrice) * srcNativeCurrencyPrice >= dstNativeCurrencyPrice);
|
|
|
|
initializeRelayProvider();
|
|
|
|
// update the prices with reasonable values
|
|
relayProvider.updatePrice(dstChainId, dstGasPrice, dstNativeCurrencyPrice);
|
|
relayProvider.updatePrice(TEST_ORACLE_CHAIN_ID, srcGasPrice, srcNativeCurrencyPrice);
|
|
|
|
// verify price
|
|
uint256 expected = (uint256(dstNativeCurrencyPrice) * (uint256(dstGasPrice)) + (srcNativeCurrencyPrice - 1))
|
|
/ srcNativeCurrencyPrice;
|
|
uint256 readValues = relayProvider.quoteGasPrice(dstChainId);
|
|
require(readValues == expected, "relayProvider.quotePrices != expected");
|
|
}
|
|
|
|
struct UpdatePrice {
|
|
uint16 chainId;
|
|
uint128 gasPrice;
|
|
uint128 nativeCurrencyPrice;
|
|
}
|
|
|
|
function testUpdatePrices(
|
|
uint16 dstChainId,
|
|
uint128 dstGasPrice,
|
|
uint64 dstNativeCurrencyPrice,
|
|
uint128 srcGasPrice,
|
|
uint64 srcNativeCurrencyPrice,
|
|
uint32 gasLimit,
|
|
uint32 deliverGasOverhead,
|
|
uint32 targetWormholeFee
|
|
) public {
|
|
vm.assume(dstChainId > 0);
|
|
vm.assume(dstChainId != TEST_ORACLE_CHAIN_ID); // wormhole.chainId()
|
|
vm.assume(dstGasPrice > 0);
|
|
vm.assume(dstNativeCurrencyPrice > 0);
|
|
vm.assume(srcGasPrice > 0);
|
|
vm.assume(srcNativeCurrencyPrice > 0);
|
|
vm.assume(dstGasPrice >= dstNativeCurrencyPrice / srcNativeCurrencyPrice);
|
|
|
|
initializeRelayProvider();
|
|
|
|
RelayProviderStructs.UpdatePrice[] memory updates = new RelayProviderStructs.UpdatePrice[](2);
|
|
updates[0] = RelayProviderStructs.UpdatePrice({
|
|
chainId: TEST_ORACLE_CHAIN_ID,
|
|
gasPrice: srcGasPrice,
|
|
nativeCurrencyPrice: srcNativeCurrencyPrice
|
|
});
|
|
updates[1] = RelayProviderStructs.UpdatePrice({
|
|
chainId: dstChainId,
|
|
gasPrice: dstGasPrice,
|
|
nativeCurrencyPrice: dstNativeCurrencyPrice
|
|
});
|
|
|
|
// update the prices with reasonable values
|
|
relayProvider.updatePrices(updates);
|
|
|
|
// verify price
|
|
uint256 expected = (uint256(dstNativeCurrencyPrice) * (uint256(dstGasPrice)) + (srcNativeCurrencyPrice - 1))
|
|
/ srcNativeCurrencyPrice;
|
|
uint256 readValues = relayProvider.quoteGasPrice(dstChainId);
|
|
require(readValues == expected, "relayProvider.quotePrices != expected");
|
|
}
|
|
}
|