1

I am trying to execute the following SC in truffle console environment:

contract MortalS {
    
    address payable public owner;

    constructor() public { owner = msg.sender; }

    function kill() payable public { if (msg.sender == owner) selfdestruct(owner); }
    function() external payable{}
    
}

The problem is that when I execute kill(), it results in the execution of selfdestruct(..) function. After the execution of selfdestruct, the balance of MortalS SC becomes zero, which is a proof of selfdestruct’s execution. I have deployed the SC using “truffle migrate” command. After that I execute the MortalS (i.e. victim). Each time Truffle system automatically generates a different address for the victim SC (i.e. different from the deployed one). Still, despite this, the if-condition is not able to protect the MortalS and its balance becomes zero due to the transfer of the entire balance as a consequence of the execution of MortalSC. I have transferred 11 Ether before executing selfdestruct from the Truffle account. The steps are:

$ truffle console
truffle(development)> const acc2 = accounts[2];
undefined
truffle(development)> acc2bal = await web3.eth.getBalance(acc2);
undefined
truffle(development)> web3.utils.fromWei(acc2bal, "ether");
'88.9995792'

truffle(development)> v = await MortalS.new()
undefined
truffle(development)> balance = await web3.eth.getBalance(v.address);
undefined
truffle(development)> web3.utils.fromWei(balance, "ether")
'0'
truffle(development)> amount = '11'
'11'
truffle(development)> result1 = await  web3.eth.sendTransaction({to:v.address, from:acc2, value: web3.utils.toWei(amount)})
undefined
truffle(development)> console.log("receipt :", result1)
receipt : { transactionHash:
   '0x8d5035beab90e92367b5243b0b36a30f163cb88b3cc19a207fb8487f25767e81',
  transactionIndex: 0,
  blockHash:
   '0x239e199918b031d8eb340af52954de35cc3db743634af4f2b4c6f72302afc3ba',
  blockNumber: 12,
  from: '0x018a1207f03801d853019ad345d17dbb0de9e091',
  to: '0xe16527ee8b3acd3a833ae3bc155c6d595422ccb7',
  gasUsed: 21040,
  cumulativeGasUsed: 21040,
  contractAddress: null,
  logs: [],
  status: true,
  logsBloom:
   '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' }
undefined
truffle(development)> console.log("sender :", result1.from)
sender : 0x018a1207f03801d853019ad345d17dbb0de9e091
undefined
truffle(development)> console.log("receiver : ", result1.to)
receiver :  0xe16527ee8b3acd3a833ae3bc155c6d595422ccb7
undefined
truffle(development)> vicbal = await web3.eth.getBalance(v.address)
undefined
truffle(development)> web3.utils.fromWei(vicbal, "ether")
'11'
truffle(development)> console.log(`Deposited ${amount} Ether from acc2:${acc2}, to victim:`, v.address,` balance is ${vicbal}`)
Deposited 11 Ether from acc2:0x018A1207f03801D853019ad345d17DBb0DE9e091, to victim: 0xe16527EE8b3acd3A833AE3bc155c6d595422cCB7  balance is 11000000000000000000
undefined
truffle(development)> vicbal = await web3.eth.getBalance(v.address)
undefined
truffle(development)> web3.utils.fromWei(vicbal, "ether")
'11'
truffle(development)> await v.kill()
{ tx:
   '0xc69005222e6c0370fc85132a5399805d0bdbd5dc68668f98c4707dc16e7c918d',
  receipt:
   { transactionHash:
      '0xc69005222e6c0370fc85132a5399805d0bdbd5dc68668f98c4707dc16e7c918d',
     transactionIndex: 0,
     blockHash:
      '0x7aa1c0fb99dec54d7cdfb3ceee24f85977c7c16ee6f352df5545bc75c468cd4a',
     blockNumber: 13,
     from: '0x9f969b6754d2d96a1b1bba037f7e996b420f38ab',
     to: '0xe16527ee8b3acd3a833ae3bc155c6d595422ccb7',
     gasUsed: 13935,
     cumulativeGasUsed: 13935,
     contractAddress: null,
     logs: [],
     status: true,
     logsBloom:
      '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
     rawLogs: [] },
  logs: [] }
truffle(development)> vicbal = await web3.eth.getBalance(v.address)
undefined
truffle(development)> web3.utils.fromWei(vicbal, "ether")
'0'
truffle(development)> 

Somebody please guide me why the if-condition is not able to protect the “selfdestruct opcode”?

Zulfi.

1 Answer 1

4

For both the victim deployment and the call to kill you don’t define what address you are using so in both case you are using the default address. So the déployer and the caller are the same, so the msg.sender == owner check passes since they are the same address.

If you call kill from any other addresses then your if condition will protect your contract

3
  • please guide me how can I change the victim to point to some other account like truffle account a[3], so that the execution of selfdestruct does not kill the Smart contract. Zulfi
    – zak100
    Nov 29, 2022 at 4:08
  • what do you mean by "Pyr f"?
    – zak100
    Nov 29, 2022 at 16:12
  • I'm not too familiar with command line truffle but with hardhad for exemple you can explicitly describe the address used to make a call by writting "theContract.connect(address[1]).call()". So you should look into truffle command line address changing Nov 29, 2022 at 19:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.