i was tried to understand the codes inside a SC on BSC recently and i found some weird codes inside the decompiled section. i know some little solidity programming and tried to use Remix to reverse it or like that.
but now im stuck on this specific character:
′
you can see in the decompiled section at this link.
so i need to tell you about this SC process:
let's grab X
and Y
as wallets and T
for tokens.
X
bought the T
and now X can not sell it.
X
tried everything like slippage/... to sell T
, but doesn't work.
X
transferred T
to Y
and now Y
can sell X
but not all of them!
it has a sell limitation option in the SC code.
so Y
tried to sell n
amount of T
by default slippage and it works (it will let Y
to sell only lower than 180,000 of T
).
Y
approved the token and it's approved on specified block of BSC.
when Y
tried to sell T
, it required a sum of series of FEEs.
the default fee on BSC for tokens is now
Gas limit = 21,000
and
Gas price(GWEI) = 5
but the T fee requesting is sum of a number that multiplied to another number; it means when Y
tried to sell n*x
of T
, it requires n+21000+Q0+Q1+...+Qn
(Qn
= unknown Real numbers (R))
so i tried to understand the process using some tricks on codes but i couldn't solve it because of the ′
.
here you can see what is happening in this SC:
# Palkeoramix decompiler.
#
# I failed with these:
# - transferFrom(address _from, address _to, uint256 _value)
# - transfer(address _to, uint256 _value)
# All the rest is below.
#
const decimals = 18
const MAX = -1
def storage:
balanceOf is mapping of uint256 at storage 0
allowance is mapping of uint256 at storage 1
totalSupply is uint256 at storage 2
stor3 is array of struct at storage 3
stor4 is array of struct at storage 4
unknownc816841bAddress is addr at storage 5
unknown03fd2a45Address is addr at storage 6
unknownf887ea40Address is addr at storage 7
def unknown03fd2a45() payable:
return unknown03fd2a45Address
def totalSupply() payable:
return totalSupply
def balanceOf(address _owner) payable:
require calldata.size - 4 >=′ 32
require _owner == _owner
return balanceOf[addr(_owner)]
def unknownc816841b() payable:
return unknownc816841bAddress
def allowance(address _owner, address _spender) payable:
require calldata.size - 4 >=′ 64
require _owner == _owner
require _spender == _spender
return allowance[addr(_owner)][addr(_spender)]
def unknownf887ea40() payable:
return unknownf887ea40Address
#
# Regular functions
#
def _fallback() payable: # default function
revert
def approve(address _spender, uint256 _value) payable:
require calldata.size - 4 >=′ 64
require _spender == _spender
require _value == _value
if not caller:
revert with 0x8c379a000000000000000000000000000000000000000000000000000000000, 'ERC20: approve from the zero address'
if not _spender:
revert with 0x8c379a000000000000000000000000000000000000000000000000000000000, 'ERC20: approve to the zero address'
allowance[caller][addr(_spender)] = _value
log Approval(
address tokenOwner=_value,
address spender=caller,
uint256 tokens=_spender)
return 1
def increaseAllowance(address _spender, uint256 _addedValue) payable:
require calldata.size - 4 >=′ 64
require _spender == _spender
require _addedValue == _addedValue
if allowance[caller][addr(_spender)] > -_addedValue - 1:
revert with 'NH{q', 17
if not caller:
revert with 0x8c379a000000000000000000000000000000000000000000000000000000000, 'ERC20: approve from the zero address'
if not _spender:
revert with 0x8c379a000000000000000000000000000000000000000000000000000000000, 'ERC20: approve to the zero address'
allowance[caller][addr(_spender)] += _addedValue
log Approval(
address tokenOwner=(allowance[caller][addr(_spender)] + _addedValue),
address spender=caller,
uint256 tokens=_spender)
return 1
def decreaseAllowance(address _spender, uint256 _subtractedValue) payable:
require calldata.size - 4 >=′ 64
require _spender == _spender
require _subtractedValue == _subtractedValue
if allowance[caller][addr(_spender)] < _subtractedValue:
revert with 0x8c379a000000000000000000000000000000000000000000000000000000000, 'ERC20: decreased allowance below zero'
if not caller:
revert with 0x8c379a000000000000000000000000000000000000000000000000000000000, 'ERC20: approve from the zero address'
if not _spender:
revert with 0x8c379a000000000000000000000000000000000000000000000000000000000, 'ERC20: approve to the zero address'
allowance[caller][addr(_spender)] -= _subtractedValue
log Approval(
address tokenOwner=(allowance[caller][addr(_spender)] - _subtractedValue),
address spender=caller,
uint256 tokens=_spender)
return 1
def name() payable:
if bool(stor3.length):
if not bool(stor3.length) - (stor3.length.field_1 < 32):
revert with 'NH{q', 34
if bool(stor3.length):
if not bool(stor3.length) - (stor3.length.field_1 < 32):
revert with 'NH{q', 34
if stor3.length.field_1:
if 31 < stor3.length.field_1:
mem[128] = uint256(stor3.field_0)
idx = 128
s = 0
while stor3.length.field_1 + 96 > idx:
mem[idx + 32] = stor3[s].field_256
idx = idx + 32
s = s + 1
continue
return Array(len=2 * Mask(256, -1, stor3.length.field_1), data=mem[128 len ceil32(stor3.length.field_1)])
mem[128] = 256 * stor3.length.field_8
else:
if not bool(stor3.length) - (stor3.length.field_1 < 32):
revert with 'NH{q', 34
if stor3.length.field_1:
if 31 < stor3.length.field_1:
mem[128] = uint256(stor3.field_0)
idx = 128
s = 0
while stor3.length.field_1 + 96 > idx:
mem[idx + 32] = stor3[s].field_256
idx = idx + 32
s = s + 1
continue
return Array(len=2 * Mask(256, -1, stor3.length.field_1), data=mem[128 len ceil32(stor3.length.field_1)])
mem[128] = 256 * stor3.length.field_8
mem[ceil32(stor3.length.field_1) + 192 len ceil32(stor3.length.field_1)] = mem[128 len ceil32(stor3.length.field_1)]
if ceil32(stor3.length.field_1) > stor3.length.field_1:
mem[ceil32(stor3.length.field_1) + stor3.length.field_1 + 192] = 0
return Array(len=2 * Mask(256, -1, stor3.length.field_1), data=mem[128 len ceil32(stor3.length.field_1)], mem[(2 * ceil32(stor3.length.field_1)) + 192 len 2 * ceil32(stor3.length.field_1)]),
if not bool(stor3.length) - (stor3.length.field_1 < 32):
revert with 'NH{q', 34
if bool(stor3.length):
if not bool(stor3.length) - (stor3.length.field_1 < 32):
revert with 'NH{q', 34
if stor3.length.field_1:
if 31 < stor3.length.field_1:
mem[128] = uint256(stor3.field_0)
idx = 128
s = 0
while stor3.length.field_1 + 96 > idx:
mem[idx + 32] = stor3[s].field_256
idx = idx + 32
s = s + 1
continue
return Array(len=stor3.length % 128, data=mem[128 len ceil32(stor3.length.field_1)])
mem[128] = 256 * stor3.length.field_8
else:
if not bool(stor3.length) - (stor3.length.field_1 < 32):
revert with 'NH{q', 34
if stor3.length.field_1:
if 31 < stor3.length.field_1:
mem[128] = uint256(stor3.field_0)
idx = 128
s = 0
while stor3.length.field_1 + 96 > idx:
mem[idx + 32] = stor3[s].field_256
idx = idx + 32
s = s + 1
continue
return Array(len=stor3.length % 128, data=mem[128 len ceil32(stor3.length.field_1)])
mem[128] = 256 * stor3.length.field_8
mem[ceil32(stor3.length.field_1) + 192 len ceil32(stor3.length.field_1)] = mem[128 len ceil32(stor3.length.field_1)]
if ceil32(stor3.length.field_1) > stor3.length.field_1:
mem[ceil32(stor3.length.field_1) + stor3.length.field_1 + 192] = 0
return Array(len=stor3.length % 128, data=mem[128 len ceil32(stor3.length.field_1)], mem[(2 * ceil32(stor3.length.field_1)) + 192 len 2 * ceil32(stor3.length.field_1)]),
def symbol() payable:
if bool(stor4.length):
if not bool(stor4.length) - (stor4.length.field_1 < 32):
revert with 'NH{q', 34
if bool(stor4.length):
if not bool(stor4.length) - (stor4.length.field_1 < 32):
revert with 'NH{q', 34
if stor4.length.field_1:
if 31 < stor4.length.field_1:
mem[128] = uint256(stor4.field_0)
idx = 128
s = 0
while stor4.length.field_1 + 96 > idx:
mem[idx + 32] = stor4[s].field_256
idx = idx + 32
s = s + 1
continue
return Array(len=2 * Mask(256, -1, stor4.length.field_1), data=mem[128 len ceil32(stor4.length.field_1)])
mem[128] = 256 * stor4.length.field_8
else:
if not bool(stor4.length) - (stor4.length.field_1 < 32):
revert with 'NH{q', 34
if stor4.length.field_1:
if 31 < stor4.length.field_1:
mem[128] = uint256(stor4.field_0)
idx = 128
s = 0
while stor4.length.field_1 + 96 > idx:
mem[idx + 32] = stor4[s].field_256
idx = idx + 32
s = s + 1
continue
return Array(len=2 * Mask(256, -1, stor4.length.field_1), data=mem[128 len ceil32(stor4.length.field_1)])
mem[128] = 256 * stor4.length.field_8
mem[ceil32(stor4.length.field_1) + 192 len ceil32(stor4.length.field_1)] = mem[128 len ceil32(stor4.length.field_1)]
if ceil32(stor4.length.field_1) > stor4.length.field_1:
mem[ceil32(stor4.length.field_1) + stor4.length.field_1 + 192] = 0
return Array(len=2 * Mask(256, -1, stor4.length.field_1), data=mem[128 len ceil32(stor4.length.field_1)], mem[(2 * ceil32(stor4.length.field_1)) + 192 len 2 * ceil32(stor4.length.field_1)]),
if not bool(stor4.length) - (stor4.length.field_1 < 32):
revert with 'NH{q', 34
if bool(stor4.length):
if not bool(stor4.length) - (stor4.length.field_1 < 32):
revert with 'NH{q', 34
if stor4.length.field_1:
if 31 < stor4.length.field_1:
mem[128] = uint256(stor4.field_0)
idx = 128
s = 0
while stor4.length.field_1 + 96 > idx:
mem[idx + 32] = stor4[s].field_256
idx = idx + 32
s = s + 1
continue
return Array(len=stor4.length % 128, data=mem[128 len ceil32(stor4.length.field_1)])
mem[128] = 256 * stor4.length.field_8
else:
if not bool(stor4.length) - (stor4.length.field_1 < 32):
revert with 'NH{q', 34
if stor4.length.field_1:
if 31 < stor4.length.field_1:
mem[128] = uint256(stor4.field_0)
idx = 128
s = 0
while stor4.length.field_1 + 96 > idx:
mem[idx + 32] = stor4[s].field_256
idx = idx + 32
s = s + 1
continue
return Array(len=stor4.length % 128, data=mem[128 len ceil32(stor4.length.field_1)])
mem[128] = 256 * stor4.length.field_8
mem[ceil32(stor4.length.field_1) + 192 len ceil32(stor4.length.field_1)] = mem[128 len ceil32(stor4.length.field_1)]
if ceil32(stor4.length.field_1) > stor4.length.field_1:
mem[ceil32(stor4.length.field_1) + stor4.length.field_1 + 192] = 0
return Array(len=stor4.length % 128, data=mem[128 len ceil32(stor4.length.field_1)], mem[(2 * ceil32(stor4.length.field_1)) + 192 len 2 * ceil32(stor4.length.field_1)]),
and the decompiler issues are:
# - transferFrom(address _from, address _to, uint256 _value)
# - transfer(address _to, uint256 _value)
after tried to do some tricks on PCS and sell it, i faced with these issues:
Swap failed: Unknown error: "[ethjs-query] while formatting outputs from RPC '{"value":{"code":-32603,"data":{"code":-32000,"message":"intrinsic gas too low"}}}'". Try increasing your slippage tolerance.
so as you can see the [ethjs-query]
is the minor issue here that cause of the bugs around here as FEE error when Y
trying to sell it on regular
Gas Limit
!
i will be appreciate your replies and guidelines for this kind of issue that we will soft-fork the Eveem's decompiler.