I am trying to understand how an exploit occurred on the Ethereum network as per PeckShield's Tweet. According to the exploit transaction logs, contract code at 0x824dcd7b044d60df2e89b1bb888e66d8bcf41491 was invoked yet somehow the old lib for MetaSwapUtils, at 0x88cc4aa0dd6cf126b00c012dda9f6f4fd9388b17, was used.


As a student of cybersecurity, it made sense to try and make a demonstration of this. I tried to replicate what the attacker made, and developed the following example.

My question is, based on the example below, how can I use the HelloUtils.sol contract to override the library used in Hello.sol, within the same call on line 6 of ContractMain.sol? So that the output of the response in line 9 of ContractMain.sol reads "Hello Jon the great!" instead of "Hello Jon the great".

HelloUtils.sol (deployed at 0x0000000000000000000000000000000000000000)

1  library HelloUtils {
2      // lets assume implementing function returns ("hello" + text + extraText + "!")
3      // please notice this appends an exclamation mark in the implementing function
4      hello(
5          string text,
6          string extraText
7      ) external view returns (string);
8  }


1  interface IHello {
2      message(
3          string name
4      ) external view returns (string); 
5  }

Hello.sol (deployed at 0x1000000000000000000000000000000000000000)

1  import "IHello.sol";
3  library HelloUtils {
4      // lets assume implementing function just returns ("hello" + text + extraText)
5      hello(
6          string text,
7          string extraText
8      ) external view returns (string);
9  }
11 contract Hello is IHello {
12     using HelloUtils for string;
14     function message(string name) external view returns (string) {
15         return name.hello("the great");
16     }
17 }


1  import "./IHello.sol";
3  contract Main {
4      address HelloAddress; // value is 0x1000000000000000000000000000000000000000
6      string response = IHello(HelloAddress).message("Jon");
8      // https://hardhat.org/guides/hardhat-console.html
9      console.log(response); // outputs something like "Hello Jon the great"
10 }

1 Answer 1


Having quickly read the tweet, it appears the author is referring to library linking (https://docs.soliditylang.org/en/latest/using-the-compiler.html?highlight=linking#library-linking)

External library calls are encoded by the solidity compiler as calls to an address that, during the compilation phase, is a placeholder "name". Then, during the linking process, the developer supplies the actual deployed address of the library. This produces the final deployable bytecode that includes a valid (hex, not "name") address to call when the bytecode is actually executed.

If the developer makes a mistake, and links vs the wrong deployed address, the wrong code will of course execute. I believe the tweet is saying that the address used during the linking phase referenced an old incorrect version of the MetaSwapUtils library.

The contract at 0x824dcd7b044d60df2e89b1bb888e66d8bcf41491 is MetaSwap. This is distinct from the library MetaSwapUtils. In other words, there is a contract MetaSwap whose authors presumably provide a utility library called MetaSwapUtils that has helpful functions for interacting with MetaSwap.

Presumably users of MetaSwap are expected to use the correct version of MetaSwapUtils, and the developer of the contract that was exploited did not reference the correct (newer) library address.

You cannot cause a contract to use a different library than the one it is statically linked to when deployed. That is, not unless it (stupidly) provides a function where you supply an address on which it will then call a function on your behalf.

In other words, the attack was not that the attacker caused the contract to use the wrong external library. Rather, it was that the attacker noticed that the contract was using the wrong external library, and exploited the resulting bugs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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