diff --git a/@types/AnyFiatTokenCeloInstance.d.ts b/@types/AnyFiatTokenCeloInstance.d.ts deleted file mode 100644 index d59577d72..000000000 --- a/@types/AnyFiatTokenCeloInstance.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -/** - * SPDX-License-Identifier: Apache-2.0 - * - * Copyright (c) 2023, Circle Internet Financial, LLC. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { FiatTokenV22InstanceExtended } from "./AnyFiatTokenV2Instance"; - -export interface AnyCeloFiatToken extends FiatTokenV22InstanceExtended { - debitGasFees?: typeof FiatTokenCeloV22Instance.debitGasFees; - creditGasFees?: typeof FiatTokenCeloV22Instance.creditGasFees; -} diff --git a/@types/AnyFiatTokenV2Instance.d.ts b/@types/AnyFiatTokenV2Instance.d.ts index 7c7590984..4cd85779f 100644 --- a/@types/AnyFiatTokenV2Instance.d.ts +++ b/@types/AnyFiatTokenV2Instance.d.ts @@ -20,16 +20,25 @@ import { FiatTokenV2Instance, FiatTokenV21Instance, FiatTokenV22Instance, + FiatTokenCeloV22Instance, } from "./generated"; -export interface FiatTokenV22InstanceExtended extends FiatTokenV22Instance { +export interface OverloadedAAFunctions { permit?: typeof FiatTokenV2Instance.permit; transferWithAuthorization?: typeof FiatTokenV2Instance.transferWithAuthorization; receiveWithAuthorization?: typeof FiatTokenV2Instance.receiveWithAuthorization; cancelAuthorization?: typeof FiatTokenV2Instance.cancelAuthorization; } +export interface FiatTokenV22InstanceExtended + extends FiatTokenV22Instance, + OverloadedAAFunctions {} +export interface FiatTokenCeloV22InstanceExtended + extends FiatTokenCeloV22Instance, + OverloadedAAFunctions {} + export type AnyFiatTokenV2Instance = | FiatTokenV2Instance | FiatTokenV21Instance - | FiatTokenV22InstanceExtended; + | FiatTokenV22InstanceExtended + | FiatTokenCeloV22InstanceExtended; diff --git a/contracts/test/celo/MockFiatTokenCeloWithCustomVmAddress.sol b/contracts/test/celo/MockFiatTokenCeloWithExposedFunctions.sol similarity index 66% rename from contracts/test/celo/MockFiatTokenCeloWithCustomVmAddress.sol rename to contracts/test/celo/MockFiatTokenCeloWithExposedFunctions.sol index 7233534bd..7e6df52be 100644 --- a/contracts/test/celo/MockFiatTokenCeloWithCustomVmAddress.sol +++ b/contracts/test/celo/MockFiatTokenCeloWithExposedFunctions.sol @@ -24,25 +24,11 @@ import { FiatTokenCeloV2_2 } from "../../v2/celo/FiatTokenCeloV2_2.sol"; /** * @dev This contract is the same as FiatTokenCeloV2_2, except, for testing, - * it allows us to arbitrarily override the address that calls the debit - * and credit functions. Truffle does not support impersonation of 0x0, so - * we must call by using a different address. + * it allows us to call internal sensitive functions for testing. These + * external test functions are prefixed with "internal_" to differentiate + * them from the main internal functions. */ -contract MockFiatTokenCeloWithCustomVmAddress is FiatTokenCeloV2_2 { - address private _vmCallerAddress; - - modifier onlyCeloVm() override { - require( - msg.sender == _vmCallerAddress, - "FiatTokenCeloV2_2: Only Celo VM can call" - ); - _; - } - - function setVmCallerAddress(address newVmCallerAddress) external { - _vmCallerAddress = newVmCallerAddress; - } - +contract MockFiatTokenCeloWithExposedFunctions is FiatTokenCeloV2_2 { function internal_debitedValue() external view returns (uint256) { return _debitedValue(); } @@ -51,7 +37,7 @@ contract MockFiatTokenCeloWithCustomVmAddress is FiatTokenCeloV2_2 { address from, address to, uint256 value - ) external onlyCeloVm { + ) external onlyFeeCaller { _transferReservedGas(from, to, value); } diff --git a/contracts/v2/celo/FiatTokenCeloV2_2.sol b/contracts/v2/celo/FiatTokenCeloV2_2.sol index 6294511dd..4d5516efc 100644 --- a/contracts/v2/celo/FiatTokenCeloV2_2.sol +++ b/contracts/v2/celo/FiatTokenCeloV2_2.sol @@ -24,15 +24,53 @@ import { ICeloGasToken } from "../../interface/celo/ICeloGasToken.sol"; contract FiatTokenCeloV2_2 is FiatTokenV2_2, ICeloGasToken { using SafeMath for uint256; + event FeeCallerChanged(address indexed newAddress); - modifier onlyCeloVm() virtual { + /** + * @notice Constant containing the storage slot indicating the current fee caller of + * `debitGasFees` and `creditGasFees`. Only the fee caller should be able to represent + * this FiatToken during a gas lifecycle. This slot starts off indicating address(0) + * as the allowed fee caller, as the storage slot is empty. + * @dev This constant is the Keccak-256 hash of "com.circle.fiattoken.celo.feecaller" and is + * validated in the contract constructor. It does not occupy any storage slots, since + * constants are embedded in the bytecode of a smart contract. This is intentionally done + * so that the Celo variant of FiatToken can accommodate new state variables that may be + * added in future FiatToken versions. + */ + bytes32 + private constant FEE_CALLER_SLOT = 0xdca914aef3e4e19727959ebb1e70b58822e2c7b796d303902adc19513fcb4af5; + + /** + * @notice Returns the current fee caller address allowed on `debitGasFees` and `creditGasFees`. + * @dev Though Solidity generates implicit viewers/getters on contract state, because we + * store the fee caller in a custom Keccak256 slot instead of a standard declaration, we + * need an explicit getter for that slot. + */ + function feeCaller() public view returns (address value) { + assembly { + value := sload(FEE_CALLER_SLOT) + } + } + + modifier onlyFeeCaller() virtual { require( - msg.sender == address(0), - "FiatTokenCeloV2_2: Only Celo VM can call" + msg.sender == feeCaller(), + "FiatTokenCeloV2_2: caller is not the fee caller" ); _; } + /** + * @notice Updates the fee caller address. + * @param _newFeeCaller The address of the new pauser. + */ + function updateFeeCaller(address _newFeeCaller) external onlyOwner { + assembly { + sstore(FEE_CALLER_SLOT, _newFeeCaller) + } + emit FeeCallerChanged(_newFeeCaller); + } + /** * @notice Constant containing the storage slot indicating the debited value currently * reserved for a transaction's gas paid in this token. This value also serves as a flag @@ -47,22 +85,25 @@ contract FiatTokenCeloV2_2 is FiatTokenV2_2, ICeloGasToken { bytes32 private constant DEBITED_VALUE_SLOT = 0xd90dccaa76fe7208f2f477143b6adabfeb5d4a5136982894dfc51177fa8eda28; - constructor() public { - assert( - DEBITED_VALUE_SLOT == keccak256("com.circle.fiattoken.celo.debit") - ); - } - function _debitedValue() internal view returns (uint256 value) { assembly { value := sload(DEBITED_VALUE_SLOT) } } + constructor() public { + assert( + DEBITED_VALUE_SLOT == keccak256("com.circle.fiattoken.celo.debit") + ); + assert( + FEE_CALLER_SLOT == keccak256("com.circle.fiattoken.celo.feecaller") + ); + } + function debitGasFees(address from, uint256 value) external override - onlyCeloVm + onlyFeeCaller whenNotPaused notBlacklisted(from) { @@ -81,17 +122,18 @@ contract FiatTokenCeloV2_2 is FiatTokenV2_2, ICeloGasToken { function creditGasFees( address from, address feeRecipient, + // solhint-disable-next-line no-unused-vars address gatewayFeeRecipient, address communityFund, uint256 refund, uint256 tipTxFee, - // solhint-disable-next-line + // solhint-disable-next-line no-unused-vars uint256 gatewayFee, uint256 baseTxFee ) external override - onlyCeloVm + onlyFeeCaller whenNotPaused notBlacklisted(from) notBlacklisted(feeRecipient) diff --git a/test/helpers/index.ts b/test/helpers/index.ts index 383013fa8..c11cfdd63 100644 --- a/test/helpers/index.ts +++ b/test/helpers/index.ts @@ -20,6 +20,7 @@ import { ecsign } from "ethereumjs-util"; import { assert } from "chai"; import { solidityPack } from "ethereumjs-abi"; import { + FiatTokenCeloV22Instance, FiatTokenProxyInstance, FiatTokenV11Instance, FiatTokenV1Instance, @@ -140,7 +141,8 @@ export async function initializeToVersion( | FiatTokenV11Instance | FiatTokenV2Instance | FiatTokenV21Instance - | FiatTokenV22Instance, + | FiatTokenV22Instance + | FiatTokenCeloV22Instance, version: "1" | "1.1" | "2" | "2.1" | "2.2", fiatTokenOwner: string, lostAndFound: string, diff --git a/test/v2/FiatTokenV2_2.test.ts b/test/v2/FiatTokenV2_2.test.ts index 6b0bdfe10..d9687f774 100644 --- a/test/v2/FiatTokenV2_2.test.ts +++ b/test/v2/FiatTokenV2_2.test.ts @@ -20,6 +20,7 @@ import BN from "bn.js"; import crypto from "crypto"; import { AnyFiatTokenV2Instance, + FiatTokenCeloV22InstanceExtended, FiatTokenV22InstanceExtended, } from "../../@types/AnyFiatTokenV2Instance"; import { @@ -411,7 +412,7 @@ export function behavesLikeFiatTokenV22( * here we re-assign the overloaded method definition to the method name shorthand. */ export function initializeOverloadedMethods( - fiatToken: FiatTokenV22InstanceExtended, + fiatToken: FiatTokenV22InstanceExtended | FiatTokenCeloV22InstanceExtended, signatureBytesType: SignatureBytesType ): void { if (signatureBytesType == SignatureBytesType.Unpacked) { diff --git a/test/v2/celo/FiatTokenCeloV2_2.test.ts b/test/v2/celo/FiatTokenCeloV2_2.test.ts index 909f3ffea..43dd1906b 100644 --- a/test/v2/celo/FiatTokenCeloV2_2.test.ts +++ b/test/v2/celo/FiatTokenCeloV2_2.test.ts @@ -16,7 +16,6 @@ * limitations under the License. */ -import { AnyCeloFiatToken } from "../../../@types/AnyFiatTokenCeloInstance"; import { usesOriginalStorageSlotPositions } from "../../helpers/storageSlots.behavior"; import { expectRevert, initializeToVersion } from "../../helpers"; @@ -26,7 +25,11 @@ import { initializeOverloadedMethods, } from "../FiatTokenV2_2.test"; import { SignatureBytesType } from "../GasAbstraction/helpers"; -import { AnyFiatTokenV2Instance } from "../../../@types/AnyFiatTokenV2Instance"; +import { + AnyFiatTokenV2Instance, + FiatTokenCeloV22InstanceExtended, +} from "../../../@types/AnyFiatTokenV2Instance"; +import { FeeCallerChanged } from "../../../@types/generated/FiatTokenCeloV22"; const SignatureChecker = artifacts.require("SignatureChecker"); const FiatTokenCeloV2_2 = artifacts.require("FiatTokenCeloV2_2"); @@ -38,8 +41,9 @@ contract("FiatTokenCeloV2_2", (accounts) => { const feeRecipient = accounts[3]; const gatewayFeeRecipient = accounts[4]; const communityFund = accounts[5]; + const feeCaller = fiatTokenOwner; - let fiatTokenCelo: AnyCeloFiatToken; + let fiatTokenCelo: FiatTokenCeloV22InstanceExtended; const getFiatToken = ( signatureBytesType: SignatureBytesType @@ -60,6 +64,8 @@ contract("FiatTokenCeloV2_2", (accounts) => { fiatTokenOwner, lostAndFound ); + // Ensure we set the debit/credit fee caller for testing. + await fiatTokenCelo.updateFeeCaller(feeCaller, { from: fiatTokenOwner }); }); describe("initialized FiatTokenCeloV2_2 contract", () => { @@ -84,14 +90,17 @@ contract("FiatTokenCeloV2_2", (accounts) => { }); }); - describe("onlyCeloVm", () => { - const errorMessage = "FiatTokenCeloV2_2: Only Celo VM can call"; + describe("onlyFeeCaller", () => { + const errorMessage = "FiatTokenCeloV2_2: caller is not the fee caller"; - it("should fail to call debitGasFees when caller is not 0x0", async () => { - await expectRevert(fiatTokenCelo.debitGasFees(from, 1), errorMessage); + it("should fail to call debitGasFees when caller is not fee caller", async () => { + await expectRevert( + fiatTokenCelo.debitGasFees(from, 1, { from: from }), + errorMessage + ); }); - it("should fail to call creditGasFees when caller is not 0x0", async () => { + it("should fail to call creditGasFees when caller is not fee caller", async () => { await expectRevert( fiatTokenCelo.creditGasFees( from, @@ -101,10 +110,51 @@ contract("FiatTokenCeloV2_2", (accounts) => { 1, 1, 1, - 1 + 1, + { from: from } ), errorMessage ); }); }); + + describe("feeCaller", () => { + // See FiatTokenCeloV2_2#FEE_CALLER_SLOT. + const feeCallerSlot = + "0xdca914aef3e4e19727959ebb1e70b58822e2c7b796d303902adc19513fcb4af5"; + + it("should return correct feeCaller", async () => { + expect(await fiatTokenCelo.feeCaller()) + .to.equal(feeCaller) + .to.equal( + web3.utils.toChecksumAddress( + await web3.eth.getStorageAt(fiatTokenCelo.address, feeCallerSlot) + ) + ); + }); + }); + + describe("updateFeeCaller", () => { + it("should fail to update fee caller when sender is not token owner", async () => { + const ownableError = "Ownable: caller is not the owner"; + await expectRevert( + fiatTokenCelo.updatePauser(from, { from: from }), + ownableError + ); + }); + + it("should emit FeeCallerChanged event", async () => { + const newFeeCaller = communityFund; + const updateFeeCallerEvent = await fiatTokenCelo.updateFeeCaller( + newFeeCaller, + { from: fiatTokenOwner } + ); + + const log = updateFeeCallerEvent.logs[0] as Truffle.TransactionLog< + FeeCallerChanged + >; + assert.strictEqual(log.event, "FeeCallerChanged"); + assert.strictEqual(log.args.newAddress, newFeeCaller); + }); + }); }); diff --git a/test/v2/celo/MockFiatTokenCeloWithCustomVmAddress.test.ts b/test/v2/celo/MockFiatTokenCeloWithExposedFunctions.test.ts similarity index 81% rename from test/v2/celo/MockFiatTokenCeloWithCustomVmAddress.test.ts rename to test/v2/celo/MockFiatTokenCeloWithExposedFunctions.test.ts index 72d63324f..02dc89543 100644 --- a/test/v2/celo/MockFiatTokenCeloWithCustomVmAddress.test.ts +++ b/test/v2/celo/MockFiatTokenCeloWithExposedFunctions.test.ts @@ -19,18 +19,18 @@ import { expectRevert, initializeToVersion } from "../../helpers"; const SignatureChecker = artifacts.require("SignatureChecker"); -const MockFiatTokenCeloV2_2WithCustomVmAddress = artifacts.require( - "MockFiatTokenCeloWithCustomVmAddress" +const MockFiatTokenCeloWithExposedFunctions = artifacts.require( + "MockFiatTokenCeloWithExposedFunctions" ); -import { MockFiatTokenCeloWithCustomVmAddressInstance } from "../../../@types/generated"; +import { MockFiatTokenCeloWithExposedFunctionsInstance } from "../../../@types/generated"; import { MAX_UINT256_BN, POW_2_255_MINUS1_HEX, ZERO_ADDRESS, } from "../../helpers/constants"; -contract("MockFiatTokenCeloWithCustomVmAddress", (accounts) => { +contract("MockFiatTokenCeloWithExposedFunctions", (accounts) => { // See FiatTokenCeloV2_2#DEBITED_VALUE_SLOT. const debitedValueSlot = "0xd90dccaa76fe7208f2f477143b6adabfeb5d4a5136982894dfc51177fa8eda28"; @@ -41,12 +41,12 @@ contract("MockFiatTokenCeloWithCustomVmAddress", (accounts) => { const feeRecipient = accounts[3]; const gatewayFeeRecipient = accounts[4]; const communityFund = accounts[5]; - const vmAddress = accounts[6]; // For these tests, explicitly declare blacklister, master minter, and pauser // variables, even though they'll be initialized to the same address as the owner. const blacklister = fiatTokenOwner; const masterMinter = fiatTokenOwner; const pauser = fiatTokenOwner; + const feeCaller = fiatTokenOwner; const debitAmount = 1e6; @@ -59,31 +59,30 @@ contract("MockFiatTokenCeloWithCustomVmAddress", (accounts) => { const additionOverflowError = "SafeMath: addition overflow"; const transferFromZeroError = "ERC20: transfer from the zero address"; - let fiatToken: MockFiatTokenCeloWithCustomVmAddressInstance; + let fiatToken: MockFiatTokenCeloWithExposedFunctionsInstance; beforeEach(async () => { await SignatureChecker.new(); - MockFiatTokenCeloV2_2WithCustomVmAddress.link(SignatureChecker); - fiatToken = await MockFiatTokenCeloV2_2WithCustomVmAddress.new(); + MockFiatTokenCeloWithExposedFunctions.link(SignatureChecker); + fiatToken = await MockFiatTokenCeloWithExposedFunctions.new(); await initializeToVersion(fiatToken, "2.2", fiatTokenOwner, lostAndFound); // Configure some minter allowance (1M) ahead of time. const mintAllowance = 1000000e6; - await fiatToken.configureMinter(vmAddress, mintAllowance, { + await fiatToken.configureMinter(feeCaller, mintAllowance, { from: masterMinter, }); // Set the from address up with some funding. - await fiatToken.mint(from, 1000e6, { from: vmAddress }); + await fiatToken.mint(from, 1000e6, { from: feeCaller }); - // Impersonate the Celo VM to not be 0x0. - await fiatToken.setVmCallerAddress(vmAddress); + await fiatToken.updateFeeCaller(feeCaller); }); describe("debitGasFees", () => { - it("should debit with correct VM caller address", async () => { + it("should debit with correct fee caller address", async () => { const balanceFrom = await fiatToken.balanceOf(from); - await fiatToken.debitGasFees(from, debitAmount, { from: vmAddress }); + await fiatToken.debitGasFees(from, debitAmount, { from: feeCaller }); expect((await fiatToken.balanceOf(from)).toNumber()).to.equal( balanceFrom.toNumber() - debitAmount ); @@ -100,16 +99,16 @@ contract("MockFiatTokenCeloWithCustomVmAddress", (accounts) => { }); it("should fail to debit again with ongoing debit", async () => { - await fiatToken.debitGasFees(from, debitAmount, { from: vmAddress }); + await fiatToken.debitGasFees(from, debitAmount, { from: feeCaller }); await expectRevert( - fiatToken.debitGasFees(from, debitAmount, { from: vmAddress }), + fiatToken.debitGasFees(from, debitAmount, { from: feeCaller }), debitInvariantError ); }); it("should fail to debit from the zero address", async () => { await expectRevert( - fiatToken.debitGasFees(ZERO_ADDRESS, debitAmount, { from: vmAddress }), + fiatToken.debitGasFees(ZERO_ADDRESS, debitAmount, { from: feeCaller }), transferFromZeroError ); }); @@ -117,7 +116,7 @@ contract("MockFiatTokenCeloWithCustomVmAddress", (accounts) => { it("should fail when contract is paused", async () => { await fiatToken.pause({ from: pauser }); await expectRevert( - fiatToken.debitGasFees(from, debitAmount, { from: vmAddress }), + fiatToken.debitGasFees(from, debitAmount, { from: feeCaller }), pausedError ); }); @@ -125,7 +124,7 @@ contract("MockFiatTokenCeloWithCustomVmAddress", (accounts) => { it("should fail when `from` is blacklisted", async () => { await fiatToken.blacklist(from, { from: blacklister }); await expectRevert( - fiatToken.debitGasFees(from, debitAmount, { from: vmAddress }), + fiatToken.debitGasFees(from, debitAmount, { from: feeCaller }), blacklistedError ); }); @@ -140,7 +139,7 @@ contract("MockFiatTokenCeloWithCustomVmAddress", (accounts) => { // The original debit always equals refund + tipTxFee + gatewayFee + baseTxFee. const refund: number = debitAmount - tipTxFee - gatewayFee - baseTxFee; - it("should credit after debit with correct VM caller address", async () => { + it("should credit after debit with correct fee caller address", async () => { const fromBalancePre = (await fiatToken.balanceOf(from)).toNumber(); const feeRecipientBalancePre = ( await fiatToken.balanceOf(feeRecipient) @@ -155,7 +154,7 @@ contract("MockFiatTokenCeloWithCustomVmAddress", (accounts) => { // In practice, this debiting and crediting sequence should always be atomic // within the Celo VM core state transition code itself. See L481 and L517 at // https://github.com/celo-org/celo-blockchain/blob/3808c45addf56cf547581599a1cb059bc4ae5089/core/state_transition.go#L426-L526. - await fiatToken.debitGasFees(from, debitAmount, { from: vmAddress }); + await fiatToken.debitGasFees(from, debitAmount, { from: feeCaller }); expect( web3.utils.hexToNumber( await web3.eth.getStorageAt(fiatToken.address, debitedValueSlot) @@ -173,7 +172,7 @@ contract("MockFiatTokenCeloWithCustomVmAddress", (accounts) => { tipTxFee, gatewayFee, baseTxFee, - { from: vmAddress } + { from: feeCaller } ); expect( web3.utils.hexToNumber( @@ -207,7 +206,7 @@ contract("MockFiatTokenCeloWithCustomVmAddress", (accounts) => { it("should fail to credit with mismatched debit amount", async () => { // (_debitedValue != refund + tipTxFee + gatewayFee + baseTxFee) - await fiatToken.debitGasFees(from, debitAmount, { from: vmAddress }); + await fiatToken.debitGasFees(from, debitAmount, { from: feeCaller }); await expectRevert( fiatToken.creditGasFees( from, @@ -219,7 +218,7 @@ contract("MockFiatTokenCeloWithCustomVmAddress", (accounts) => { tipTxFee, gatewayFee, baseTxFee, - { from: vmAddress } + { from: feeCaller } ), creditInvariantError ); @@ -237,14 +236,14 @@ contract("MockFiatTokenCeloWithCustomVmAddress", (accounts) => { tipTxFee, gatewayFee, baseTxFee, - { from: vmAddress } + { from: feeCaller } ), creditInvariantError ); }); it("should fail to credit when total amount can overflow (SafeMath)", async () => { - await fiatToken.debitGasFees(from, debitAmount, { from: vmAddress }); + await fiatToken.debitGasFees(from, debitAmount, { from: feeCaller }); await expectRevert( fiatToken.creditGasFees( from, @@ -255,14 +254,14 @@ contract("MockFiatTokenCeloWithCustomVmAddress", (accounts) => { MAX_UINT256_BN, MAX_UINT256_BN, MAX_UINT256_BN, - { from: vmAddress } + { from: feeCaller } ), additionOverflowError ); }); it("should fail when contract is paused", async () => { - await fiatToken.debitGasFees(from, debitAmount, { from: vmAddress }); + await fiatToken.debitGasFees(from, debitAmount, { from: feeCaller }); await fiatToken.pause({ from: pauser }); await expectRevert( fiatToken.creditGasFees( @@ -274,14 +273,14 @@ contract("MockFiatTokenCeloWithCustomVmAddress", (accounts) => { tipTxFee, gatewayFee, baseTxFee, - { from: vmAddress } + { from: feeCaller } ), pausedError ); }); it("should fail when `from` is blacklisted", async () => { - await fiatToken.debitGasFees(from, debitAmount, { from: vmAddress }); + await fiatToken.debitGasFees(from, debitAmount, { from: feeCaller }); await fiatToken.blacklist(from, { from: blacklister }); await expectRevert( fiatToken.creditGasFees( @@ -293,14 +292,14 @@ contract("MockFiatTokenCeloWithCustomVmAddress", (accounts) => { tipTxFee, gatewayFee, baseTxFee, - { from: vmAddress } + { from: feeCaller } ), blacklistedError ); }); it("should fail when `feeRecipient` is blacklisted", async () => { - await fiatToken.debitGasFees(from, debitAmount, { from: vmAddress }); + await fiatToken.debitGasFees(from, debitAmount, { from: feeCaller }); await fiatToken.blacklist(feeRecipient, { from: blacklister }); await expectRevert( fiatToken.creditGasFees( @@ -312,14 +311,14 @@ contract("MockFiatTokenCeloWithCustomVmAddress", (accounts) => { tipTxFee, gatewayFee, baseTxFee, - { from: vmAddress } + { from: feeCaller } ), blacklistedError ); }); it("should fail when `communityFund` is blacklisted", async () => { - await fiatToken.debitGasFees(from, debitAmount, { from: vmAddress }); + await fiatToken.debitGasFees(from, debitAmount, { from: feeCaller }); await fiatToken.blacklist(communityFund, { from: blacklister }); await expectRevert( fiatToken.creditGasFees( @@ -331,7 +330,7 @@ contract("MockFiatTokenCeloWithCustomVmAddress", (accounts) => { tipTxFee, gatewayFee, baseTxFee, - { from: vmAddress } + { from: feeCaller } ), blacklistedError ); @@ -347,24 +346,24 @@ contract("MockFiatTokenCeloWithCustomVmAddress", (accounts) => { it("should fail when 0 reserved gas is requested", async () => { await expectRevert( - fiatToken.internal_transferReservedGas(from, vmAddress, 0, { - from: vmAddress, + fiatToken.internal_transferReservedGas(from, ZERO_ADDRESS, 0, { + from: feeCaller, }), zeroGasError ); }); it("should fail when _to's balance will exceed 2^255 - 1", async () => { - // Granting enough balance to vmAddress - await fiatToken.internal_setBalance(vmAddress, POW_2_255_MINUS1_HEX); + // Granting enough balance to feeCaller + await fiatToken.internal_setBalance(feeCaller, POW_2_255_MINUS1_HEX); await fiatToken.internal_setBalance(from, validTransferAmt); await expectRevert( fiatToken.internal_transferReservedGas( - vmAddress, + feeCaller, from, POW_2_255_MINUS1_HEX, - { from: vmAddress } + { from: feeCaller } ), balanceExceededError ); @@ -373,11 +372,11 @@ contract("MockFiatTokenCeloWithCustomVmAddress", (accounts) => { it("should fail when _from's balance < _value", async () => { await expectRevert( fiatToken.internal_transferReservedGas( - vmAddress, + feeCaller, from, - (await fiatToken.balanceOf(from)).toNumber() + 100, + (await fiatToken.balanceOf(feeCaller)).toNumber() + 100, { - from: vmAddress, + from: feeCaller, } ), balanceInsufficientError