Elevator

calling other contract

Description

This elevator won't let you reach the top of your building. Right?

Things that might help:

  • Sometimes solidity is not good at keeping promises.

  • This Elevator expects to be used from a Building.

Background Knowledge

Ethereum Book

External Contract Referencing - Mastering Ethereum

Code Audit

Note that the function isLastFloor() is called through an interface. When Building building = Building(msg.sender) is executed, the target contract looks for isLastFloor() in the msg.sender contract and grabs its content.

This feature was designed for modularity, but it paves the way for vulnerability since the content of msg.sender contract is out of control. As an attacker, we can deploy our own contract and implement a "malicious" version of isLastFloor() to trick the target contract.

In the function goTo(), isLastFloor() is called twice:

We want building.isLastFloor(_floor) == false and building.isLastFloor(floor) == true. Thinking abstractly, we just want isLastFloor() evaluates to false when it is called the first time, and evaluates to true when it is called the second time. This "alternating" feature can be implemented with a counter.

Solution

Write an exploit contract in Remix IDE:

Deploy it and call the attack function.

Summary

You can use the view function modifier on an interface in order to prevent state modifications. The pure modifier also prevents functions from modifying the state. Make sure you read Solidity's documentation and learn its caveats.

An alternative way to solve this level is to build a view function which returns different results depends on input data but don't modify state, e.g. gasleft().

Last updated