지능 계약 모호화

어떻게 두더지 가장자리의 병례를 발견합니까


어, 어이구!
지능 계약을 작성하는 것은 겁이 많은 사람에게 적합하지 않다.
최근에 나는 Yield Protocol의 오프라인에 참여했다.들어보지 못한 사람들에게는 이더리움의 고정금리 대출 플랫폼이다.지능 계약의 가장자리에 있는 수학 공식도 실현했다.
Yield Protocol도 배포 즉시 잊어버리는 플랫폼이다.일단 우리가 상장되면 우리는 사용자와 우리의 소프트웨어의 상호작용을 막을 수 없고 핵심 계약의 어떠한 빈틈도 복구할 수 없다.

We could go up like a rocket, and then explode.


그러나 우리는 없다. 우리는 놀라운 작은 실수가 하나 있는데, 그 중 핵심 스마트 계약은 하나도 없다.
원인 중 하나는 모호기를 사용하여 단원이나 집적 테스트로 찾을 수 없는 가장자리를 찾는 것이다.모호기를 사용하는 것은 아직 흔한 일이 아니다. 많은 사람들이 나에게 이 글을 쓰고 그들의 계약을 모호하게 하는 것을 도와달라고 요구한다.도착했습니다.
모호함은 무엇입니까?
fuzzing에 이르러 나는 의외의 결과가 발생하는 값을 찾아내기 위해 대량이나 무작위 장면을 테스트하는 것을 알게 되었다.
https://medium.com/media/1eaeb580ff20ffea52133c4016eedb46/href
예를 들어 수익률에서 우리는 분수지수를 계산하는데 분수지수는 교체하여 계산한 것이기 때문에 이더리움에서 운행하는 것은 매우 비싸다. 왜냐하면 이더리움에서 모든 조작에 돈을 써야 하기 때문이다.
사용자에게 돈을 절약하기 위해 우리는 수익률로 해커를 공격했다exponential calculation algorithm to stop calculating decimals after a while.불리한 점은 우리의 스마트 계약의 현재 거래 가격이 수학적 이상적인 무작위 수량에서 벗어난다는 것이다.
그런데 얼마나 멀어졌어요?우리는 그것을 가격을 이상적인 가격의 1센트 이내로 유지할 수 있습니까?
유일하게 아는 방법은 대량의 랜덤 장면으로 스마트 계약을 테스트하는 것이다.Trail of Bits 코드 감사 기간에 모호기를 사용하는 것이 우리가 어떻게 이 점을 할 수 있는지 알려준다.
어떻게 모호한가
우선, 너는 반드시 install echidna 해야 한다.웹 사이트의 옵션에서 나는 Ubuntu의 미리 컴파일된 바이너리 파일을 다운로드하는 데 성공했다.이를 위해서는 cryptic-compileslither 을 설치해야 합니다.나는 내가 몇 번의 노력을 들여서야 그것을 완성한 것을 기억한다. 이것은 최근에 보기 드문 일이다. 모든 물건이 npm 가방에 있다.

Fuzzing is not easy, the tools are rough, and the math is hard, but it is worth it.


만약 당신이 도움을 필요로 한다면, 당신은 채널에 가입해야 합니다.
Empire Hacking Slack 많은 문서와 강좌가 있어서 나는 전혀 이해할 수 없다.내 목숨을 구해준 것은 구스타보 그리코(Gustavo Grieco)의 운행 예시였다. 그 이후로 나는 그것을 조정하고 다시 사용했다.아마도 언젠가는 나는 더욱 정교한 세부 사항을 배울 것이다.
간단히 말하면, 당신은 설정이 필요합니다.yaml 파일, 이것은 나의 것이다.
seqLen: 50
testLimit: 20000
prefix: “crytic_”
deployer: “0x41414141”
sender: [“0x42424242”, “0x43434343”]
cryticArgs: [“ — compile-force-framework”, “Buidler”]
coverage: true
checkAsserts: true
너의 이 일에 대한 추측은 나와 마찬가지로 좋다.RTFM.아니요.
그리고 테스트할 불변량으로 견고한 계약을 작성합니다. 이 계약 테스트echidna github의muld 함수입니다.
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.6.10;

import "../helpers/DecimalMath.sol";


/// [@dev](http://twitter.com/dev) Implements simple fixed point math mul and div operations for 27 decimals.
contract DecimalMathInvariant is DecimalMath {

function muld_(uint256 x, uint256 y)
    public pure returns (uint256)
  {
    uint z = muld(x, y);

    assert((x * y) / UNIT == z); // Assert math
    assert (divd(z, y) <= x); // We are rounding down
    // Assert revert on overflow
    if(y > UNIT) assert(z >= x); // x could be zero
    if(y < UNIT) assert(z <= x); // y could be zero
  }
}
우리는 본 계약의 DecimalMath.sol 함수를 20000회 호출할 것이다.바늘두더지는 공공이기 때문에 이 함수를 실행해야 한다는 것을 안다.이 함수는 두 개의 매개 변수 (x와 y) 가 있기 때문에 바늘두더지는 실행할 때마다 이 매개 변수에 무작위 값을 사용합니다.
바늘두더지가 운행할 때, 그것은 필요로 인해 회복은 성공적이라고 생각했지만, 단언으로 인해 회복은 실패했다.
위의 계약에서 나는 부동점 곱셈의 네 가지 속성을 검사했다.
  • x*y=z, 쉼표 대체.
  • DecimalMathInvariant.muld_을 반올림(단언 z/y<=x를 통해 쉼표를 대체).
  • y가 1보다 크면 z가 x보다 크다. (넘침이 있으면 성립되지 않는다.)
  • 만약에 y가 1보다 작으면z도 x보다 작다(만약에 저류가 존재한다면 상황은 그렇지 않다).
    DecimalMath.muld
  • 인코딩 불변량은 원시 스마트 계약의 코드를 반복하지 않고 시종일관 진실한 속성을 찾아서 어떤 내용을 테스트하는 방법을 생각하게 합니다.불변량을 찾는 것은 통상적으로 매우 어렵다. 이렇게 할 때, 당신은 반드시 업무 전문가의 도움을 받아야 한다.
    검사 https://medium.com/media/813a305cc73b77793ac5a7f774f52159/href 를 통해 테스트 중인 모든 변수를 확인할 수 있습니다.침두더지는 계약 중의 모든 공공 기능을 이행할 것이다.
    현재 당신은 이미 테스트를 준비:
    $ echidna-test . — contract DecimalMathInvariant — config contracts/invariants/config.yaml
    
    이 두 파라미터는 the full contract입니다. 우리는 그 중에서 불변량을 인코딩했습니다. (우리가 테스트 중인 목표 계약도 경로도 아닙니다.)두 번째 매개 변수는 이전name of the contract이다.
    침두더지는 계약을 분석하고 계약을 맺는 데 시간이 좀 걸릴 것이다. 결국은 다음과 같다.
    path to the .yaml file 영광
    더 좋음
    너는 안에 이상한 것이 있다는 것을 알아차릴 수 있을 것이다.우리가 모호하게 하고 있는 이 단원은 무엇입니까?
    불변량 열기 및 닫기
    현재, 파일에서 틀림없이 이렇게 하는 방법이 있을 것이다. 그러나 나는 함수의 가시성을 사용하여 변수를 열고 닫는다.
    침두더지는 당신의 계약 중의 모든 공공 기능에 대해 모호하게 처리할 것이다.그건 니가 원하는 게 아닐 수도 있어.때때로, 당신은 계약 중의 10배가 아니라 문제를 일으키는 함수를 테스트하고 싶을 수도 있고, 그 중 9배가 통과할 수도 있습니다.때때로 모호하고 싶지 않은 조수 함수가 있을 수도 있습니다.
    이 경우, 함수를 내부 함수로 성명하기만 하면 바늘두더지는 무시합니다.모든 상태 변수도 내부 변수로 표시하지 않으면 무의미한 모호해진다.
    yaml
    https://medium.com/media/6896daab148cd364501f7a40b8440ce7/href에서 나는 생산량 백서의 불변량을 계산하는 데 도움을 주는 보조 함수를 가지고 있다.나는 다른 곳에서 이 함수를 사용할 것이다. 나는 단독으로 그것을 테스트하고 싶지 않다. 왜냐하면 나는 그것이 상하문 밖에서 작동하는지 확인할 수 없기 때문이다.
    this file에서 나는 심지어 변하지 않는 테스트 함수를 가지고 내부화를 통해 주석을 달았다.이것은 개발이 남긴 것이니 깨끗이 정리해야 한다. 얼마나 난처한가.
    same file에서 상수가 한 무더기 있는데 모두 내부적이다.만약 그들이 공공적이라면 두더지는 그들의 기능을 고려하여 모호화시킬 것이다. 예를 들어 UNIT처럼 UNIT는 아버지의 계약을 계승하는데 공교롭게도 공공이기 때문에 모호해졌다.
    이것은 내가 쓴 첫 번째 모호한 계약이다. 이것은 행운이다. 왜냐하면 창고나 무상태 계약으로서 그것들은 모호하기 쉽기 때문이다.내가 모호화top를 연구하기 시작한 지 얼마 되지 않아, 이것은 나로 하여금 내가 한 모든 일이 매우 틀렸다는 것을 알게 했다.
    모호 상태 계약
    나는 수학 라이브러리뿐만 아니라 모호하게 상태를 유지하는 계약이 곧 필요하다.생각해 보니 바늘두더지가 진행한 테스트는 고립적으로 진행된 것이 아니었다.
    바늘두더지는 고장이 날 때까지 계약의 함수를 무작위로 운행한다.나는 stateful contracts 파일의 seqLen 매개 변수는 하나의 서열에 몇 개의 함수 호출이 있는지 정의해야 한다고 생각한다.
    시퀀스에서 상태는 변하지 않습니다.테스트할 계약에서 변하지 않는 계약을 계승하는 것과 달리 더 좋은 방법은 그것들을 한데 연결하는 것이다. 예를 들어 .yaml의 예시와 같다.
    contract WETH10Fuzzing {
      WETH10 internal weth;
      address internal holder;
    
      /// [@dev](http://twitter.com/dev) Instantiate the WETH10 contract, and a holder address
      /// that will return weth when asked to.
      constructor () {
        weth = new WETH10();
        holder = address(new MockHolder(address(weth), address(this)));
      }
    
    내가 모든 함수를 단독으로 테스트하기 전에, 지금은 상태를 보류했다.바늘두더지는 WETH10에서 함수를 실행하여 실패한 단언을 찾을 것이다.내 불변 테스트 함수는 현재 다음과 같다.
    /// [@dev](http://twitter.com/dev) Test that supply and balance hold on deposit.
    function deposit(uint ethAmount) public {
      uint supply = weth.totalSupply();
      uint balance = weth.balanceOf(address(this));
      weth.deposit{value: ethAmount}();
    
      assert(weth.totalSupply() == add(supply, ethAmount));
      assert(weth.balanceOf(address(this)) == add(balance, ethAmount));
      assert(address(weth).balance == weth.totalSupply());
    }
    
    /// [@dev](http://twitter.com/dev) Test that supply and balance hold on withdraw.
    function withdraw(uint ethAmount) public {
      uint supply = weth.totalSupply();
      uint balance = weth.balanceOf(address(this));
      weth.withdraw(ethAmount);
    
      assert(weth.totalSupply() == sub(supply, ethAmount));
      assert(weth.balanceOf(address(this)) == sub(balance, ethAmount));
      assert(address(weth).balance == weth.totalSupply());
    }
    
    이것 때문에 저는 WETH10이 이전에 어떤 상태에 있었든지 간에 공급과 잔액은 예금과 인출에 따라 변화할 수 있는지 테스트하고 있습니다.당신은 그것을 사용하여 더욱 복잡한 다중 계약 설정을 구축할 수 있습니다.
    디버그 모호
    모든 테스트가 통과되었을 때, 이것은 매우 좋았다.처음 이런 상황이 발생하지 않으면, 당신은 의심을 품고 테스트 인코딩 오류를 가정해야 합니다.그러니까 일단 테스트를 실패시켜야 돼.
    WETH10 우리가 그것을 망가뜨렸어!예!
    테스트에 실패했을 때, 두더지는 단언에 실패한 함수를 조합하는 것을 발견할 것이다.그리고 이 고장을 일으키는 가장 짧은 서열을 찾아내서 보통 한 개 혹은 두 개의 호출로 줄일 것이다.바늘두더지가 실행하는 함수 호출을 알려줄 것이다. 이렇게.
    로그, 특정 단언에 실패한 정보, 상태 변수의 내용을 얻을 수 없습니다.실패의 원인을 알기란 쉽지 않다.
    truffle 컨트롤러나 에서 이 서열을 실행해야 합니다. 이 특정한 사례로 스마트 계약을 검증하고 단언 실패의 원인을 조사할 수 있습니다.
    만약 바늘두더지가 나에게 나의'다이를 매입하고 거래를 반전시키는 것'불변량이 어떤 매개 변수에서 실패한다고 알려준다면, 나는 그것들을 테스트 파일에 붙여서 모호한 계약의 동반자로 삼을 것이다.그리고 나는 모든 관련 변수를 저장하고 전통적인 설정에서 디버깅을 시작할 수 있다.
    결론
    모호함은 쉽지 않고 도구가 거칠고 수학은 어렵지만 가치가 있다.
    Fuzzing은 나로 하여금 자신의 스마트 계약에 대해 전대미문의 자신감을 가지게 했다.이제는 단원 테스트와 테스트망에 의존해 돌아다니는 것은 무모한 것 같다.
    그렇습니다.이렇게 많을 줄 알았어.이것은 많지 않지만, 나에게 있어서 지금까지의 효과는 매우 좋다.이렇게 멀리 가줘서 고마워요. 행운을 빌어요!

    일반 테스트 파일에서 또한 읽으십시오


  • 최고의 비트코인Best Crypto Trading Bots
  • 최고Hardware wallet
  • Crypto Tax Software
  • Best Crypto Trading Platforms
  • 최적 Best Wallet for Uniswap

  • Crypto Lending Platforms 대 호드나트
  • BlockFi vs Celsius
  • Ledger vs Trezor

  • Top DeFi Projects  — 쉽게 돈을 벌 수 있는 암호화 거래 로봇

  • Bitsgap review - 전문가를 위한 암호화 거래 로봇

  • Quadency Review | 우수한 암호화 거래 로봇
  • 3commas Review
  • 바보 안내서 3Commas vs Cryptohopper
  • 최종 안내서Margin Trading on Bitmex
  • Crypto Swing Trading

  • Bitmex Advanced Margin Trading Guide 개발업체

  • Best Crypto APIs 안내: 초보자는 어떻게 돈을 버는가
  • 최고급 Crypto arbitrage 공급업체
  • 최적 Bitcoin Node
  • 무엇입니까?
  • Get Best Software Deals Directly In Your Inbox


    Crypto Charting Tool

    좋은 웹페이지 즐겨찾기