'Solidity with Remix. Pos: 63:4: Infinite GAS cost & Pos: 88:24: Data truncated
I have two questions regarding
- Pos: 63:4: Infinite GAS cost,
- Pos: 88:24: Data truncated.
The code snippet below uses an interface, which polls a token exchange rate in order to estimate the equivalent amount of tokens given a number of tokens to swap from. I am using a readily deployed contract PancakeRouter in BSC Mainnet. The example use case that I tested after deploying this contract reads
uint m_BUSD_ante = 10;
uint[] RateTaker = [1000000000000000000, 28664197599903540];
uint HCT_ante = (10 x 1000000000000000000) / 28664197599903540
= (1E+19) / 28664197599903540
= 348.86725732150450064024231831739
= 348,
which looks reasonable to me. However, in Remix, I encounter the following warnings:
Pos: 63:4: Gas costs: Gas requirement of function TestAnte.GetHctAnte is infinite:
If the gas requirement of a function is higher than the block gas limit,
it cannot be executed. Please avoid loops in your functions or actions
that modify large areas of storage (this includes clearing or copying arrays in storage)
Pos: 88:24: Data truncated: Division of integer values yields an integer value again.
That means e.g. 10 / 100 = 0 instead of 0.1 since the result is an integer again.
This does not hold for the division of (only) literal values since those yield
rational constants.
- I don't quite understand how the GAS fee can become infinite using
GetHctAnte(). Can you help me to improve the way I should write such a contract? - According to the official Solidity documentation (https://docs.soliditylang.org/en/v0.8.10/types.html), any intermediate divisions among integers, before it returns, use rational numbers internally. Maybe, my understanding is wrong if this rule applies only to
literalintegers that one gave value explicitly, not arbitrary integer operands. If I say that I accept a fractional result less than one to be integer zero, then I don't see a problem. Can you suggest to me if there is a better practice? As far as I know, there is no explicit way to force operations to use floating points, which makes me unconfident in doing any mathematics with Solidity.
The relevant part from the official documentation reads
Division on integer literals used to truncate in Solidity
prior to version 0.4.0, but it now converts into a rational
number, i.e. 5 / 2 is not equal to 2, but to 2.5.
The code snippet of my toy contract reads
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.6;
/* Contract Name: PancakeRouter
* Contract Address: 0x10ED43C718714eb63d5aA57B78B54704E256024E
* Blockchain: BNB Chain Mainnet
* BSCScan URL: https://bscscan.com/address/0x10ED43C718714eb63d5aA57B78B54704E256024E#code
* Remark: Contract Source Code Verified (Exact Match)
*/
contract TestAnte
{
uint private m_BUSD_ante = 10;
function GetHctAnte()
public view returns (uint)
{
/* RateTaker := [HCT amount, BUSD amount], output
* TOKEN_ADDRS := [HCT-address, BUSD-address], input
*/
address[] memory TOKEN_ADDRS = new address[](2);
TOKEN_ADDRS[0] = 0x29A1e54DE0fCE58E1018535d30aF77A9d2D940c4; /* HCT */
TOKEN_ADDRS[1] = 0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56; /* BUSD */
uint[] memory RateTaker = new uint[](2);
RateTaker = PancakeRouter(
0x10ED43C718714eb63d5aA57B78B54704E256024E).getAmountsOut(
1000000000000000000, TOKEN_ADDRS);
/* 1e18 */
assert(RateTaker[1] > 0); /* [HCT: 1e18, BUSD: ? > 0] */
/* HCT = BUSD x (HCT / BUSD)
* = (10 x 1e18) / ?
*/
uint HCT_ante = (m_BUSD_ante * RateTaker[0]) / RateTaker[1];
return HCT_ante;
}
}
/* ----------------------------------------------------------------------------------
Specify Interface from Readily Deployed Contract
---------------------------------------------------------------------------------- */
interface PancakeRouter
{
function getAmountsOut(uint amountIn, address[] calldata path)
external view returns (uint[] memory amounts);
}
Thanks tons for helping me out.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
