[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nindent_style = space\nindent_size = 4\nend_of_line = lf\ninsert_final_newline = true\n"
  },
  {
    "path": ".github/workflows/main.yml",
    "content": "name: Lint, build, and deploy\non: [push, pull_request]\n\njobs:\n  build:\n    name: Test and deploy\n    runs-on: ubuntu-latest\n    env:\n      SHOULD_DEPLOY: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}\n    steps:\n      - name: Clone the repository\n        uses: actions/checkout@v2\n      - name: Install Python 3.8\n        uses: actions/setup-python@v2\n        with:\n          python-version: 3.8\n      - name: Install requirements\n        run: pip install -r requirements.txt\n      - name: Build the site with mkdocs\n        run: mkdocs build\n      # Disabled as Github IPs trigger a 403 on Etherscan.\n      # - name: Check dead links\n      #   run: linkcheckMarkdown -r --sync docs\n      - name: Deploy to Github Pages\n        if: fromJSON(env.SHOULD_DEPLOY)\n        run: mkdocs gh-deploy --force\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\n.tmp\n.vscode/\n\n# virtualenv directory\n/venv\n.python-version\n\n# build directory\n/site\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to the Smart Contract Security Best Practices\n\nPlease take a moment to review this document to make the contribution\nprocess easy and effective for everyone involved. Following these guidelines\nhelps to communicate that you respect the maintainers' time in managing and\ndeveloping this open-source project. They should reciprocate that\nrespect in addressing your issue or assessing pull requests.\n\n## Using the Issue Tracker\n\nThe issue tracker is the preferred channel for feature requests and submitting\npull requests. There are some cases where the issue tracker should not be used:\n\n-   Please **do not** use the issue tracker for personal support requests to ask\n    the community for help. There are many Discord and Telegram communities\n    around Smart Contract development where people will be more than happy to\n    help.\n-   Please **do not** derail or troll issues. Keep the discussion on topic and\n    respect the opinions of others.\n\n## Content-related Issues\n\nSections on attacks and security best practices should include examples and\nfurther reading. Security-related information is bound to change over time,\nhowever. Content-related issues should flag areas that need more explanations\nor contain outdated content.\n\nA well-written issue flagging areas of the Best Practices that need attention\nare very beneficial - thank you! Some guidelines for content-related issues:\n\n1. **Use the GitHub issue search:** Check if the issue has already been\n   reported. If the issue is already present, use a thumbs-up reaction to\n   help the developers prioritize.\n2. **Check if the issue has been fixed:** Try checking out open pull requests\n    and development branches. The problem you are looking to flag might already\n    be fixed.\n3. **Isolate the problem:** An excellent content-related issue shouldn't leave\n    others needing to chase you up for more information. Please try to be as\n    detailed as possible. If content needs fixing across multiple areas,\n    please flag one issue for each case.\n\n## Feature Requests\n\nFeature requests are welcome. But take a moment to find out whether your idea\nfits with the scope and aims of the project. It's up to _you_ to make a solid\ncase to convince the maintainers of the merits of an additional piece of content.\nPlease provide as much detail and context as possible. Keep in mind that the\nBest Practices do not aim to mirror general security considerations that can\nbe found in the project's respective documentation. Additional content to the\nrepository should be original and flag potential pitfalls developers\nmight encounter when building Smart Contract systems.\n\n## Pull Requests\n\nReasonable pull requests - patches, improvements, new content - are a fantastic help.\nThey should remain focused in scope and avoid containing unrelated commits.\n**Please ask first** before embarking on any significant pull request (e.g.\nadding new content, refactoring example code). Otherwise, you risk spending a\nlot of time working on something that the maintainers might not want to merge\ninto the project. Please adhere to the coding conventions used throughout the\nproject (indentation, comments, etc.). Adhering to the following this process\nis the best way to get your work merged:\n\n1. [Fork](http://help.github.com/fork-a-repo/) the repo, clone your fork,\n   and configure the remotes:\n    ```bash\n    # Clone your fork of the repo into the current directory\n    git clone https://github.com/<your-username>/<repo-name>\n    # Navigate to the newly cloned directory\n    cd <repo-name>\n    # Assign the original repo to a remote called \"upstream\"\n    git remote add upstream https://github.com/<upsteam-owner>/<repo-name>\n    ```\n2. If you cloned a while ago, get the latest changes from upstream:\n    ```bash\n    git checkout <dev-branch>\n    git pull upstream <dev-branch>\n    ```\n3. Create a new topic branch (off the main project development branch) to\n   contain your new content, change, or fix:\n    ```bash\n    git checkout -b <topic-branch-name>\n    ```\n4. Commit your changes in logical chunks. Please adhere to these [git commit\n   message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)\n   or your code is unlikely to be merged into the main project. Use Git's\n   [interactive rebase](https://help.github.com/articles/interactive-rebase)\n   feature to tidy up your commits before making them public.\n5. Locally merge (or rebase) the upstream development branch into your topic branch:\n    ```bash\n    git pull [--rebase] upstream <dev-branch>\n    ```\n6. Push your topic branch up to your fork:\n    ```bash\n    git push origin <topic-branch-name>\n    ```\n7. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/)\n   with a clear title and description.\n\n## Style Guidelines\n\nTo maintain a consistent writing style across the documents, a few\nconsiderations need to be taken.\n\n1. **Succinctness:** Use precise language and don't assume knowledge beyond\n    Solidity and Ethereum basics.\n2. **Show, don't tell:** Examples speak more than a lengthy exposition.\n    Provide code examples where relevant and raise issues or best practices\n    in the code around them.\n3. **Give credit:** When further reading is recommended or resources are\n    available that corroborate security issues, they should contain credit\n    and link to the original resource.\n4. **Label code:** Examples containing code must be labeled as insecure or\n    secure where relevant. Specifically, in content regarding attacks,\n    vulnerable code should be preceded by `// INSECURE`.\n"
  },
  {
    "path": "README-vi.md",
    "content": "# Smart contract best practices\n\n**Notice: this translation was generously provided by a contributor. The maintainers are not able to verify the content. Any issues or PRs to help improve it are welcome.**\n\nBài viết này được dịch nguyên văn từ https://consensys.github.io/smart-contract-best-practices. Để phù hợp với các diễn đạt văn phong tiếng việt, chúng tôi cố gắng diễn đạt tư tưởng của tài liệu chứ không dịch theo từng chữ một.\n\n- [**Những lời khuyến nghị cho việc phát triển hợp đồng thông minh bằng Solidity**](#solidity-tips)\n- [**Hiểu biết về các phương thức tấn công phổ biến**](#known-attacks)\n- [**Áp dụng các nguyên tắc trong phát triển phần mềm để viết hợp đồng thông minh**](#eng-techniques)\n- [**Lời khuyên cho việc implement mã token**](#token)\n- [**Tài liệu và thủ tục**](#document)\n- [**Các công cụ bảo mật**](#tools)\n- [**EIPs**](#eip)\n- [**Các tài nguyên tham khảo**](#resource)\n\n<a name=\"solidity-tips\"></a>\n\n# Những khuyến nghị cho việc phát triển hợp đồng thông minh an toàn bằng solidity\n\n### Lời gọi ngoài (External Calls)\n\n#### Hãy thật cẩn trọng khi sử dụng external calls\n\nCác message gọi đến những hợp đồng không đáng tin cậy có thể gây ra một số rủi ro hoặc lỗi không mong muốn. Các lời gọi ngoài có thể thực thi mã độc trong hợp đồng đó hoặc bất kỳ hợp đồng nào khác mà nó phụ thuộc vào. Như vậy, mọi lời gọi ngoài nên được xem là ẩn chứa rủi ro bảo mật. Trong trường hợp bất khả kháng, hãy sử dụng các đề xuất dưới đây để giảm thiểu rủi ro có thể xảy ra.\n\n#### Đánh dấu các hợp đồng không đáng tin cậy\n\nKhi tương tác với các lời gọi ngoài, tên các biến, phương thức và các interface nên được đặt sao cho nó thể hiện được việc tương tác với các lời gọi từ bên ngoài có an toàn hay là không ? Điều này áp dụng cho các hàm mà nó có thể được gọi từ các hợp đồng bên ngoài.\n\n```javascript\n// bad\nBank.withdraw(100); // Unclear whether trusted or untrusted\n\nfunction makeWithdrawal(uint amount) { // Isn't clear that this function is potentially unsafe\n    Bank.withdraw(amount);\n}\n\n// good\nUntrustedBank.withdraw(100); // untrusted external call\nTrustedBank.withdraw(100); // external but trusted bank contract maintained by XYZ Corp\n\nfunction makeUntrustedWithdrawal(uint amount) {\n    UntrustedBank.withdraw(amount);\n}\n```\n\n#### Tránh sử dụng `transfer()` và `send()`\n\n`.transfer()` và `.send()` giới hạn chính xác 2.300 gas lời gọi. Mục tiêu của quy định nhằm để ngăn ngừa các lỗ hổng reentrancy, nhưng điều này chỉ có ý nghĩa theo giả định rằng chi phí gas là không đổi. Gần đây EIP 1283 (được hỗ trợ từ hard fork Constantinople vào phút cuối) và EIP 1884 (dự kiến ​​sẽ đến hard fork Istanbul) sẽ làm cho việc gửi tiền bằng hai hàm này không thực sự an toàn nữa.\n\nĐể tránh mọi thứ bị đổ bể khi chi phí gas thay đổi trong tương lai, tốt nhất nên sử dụng `.call.value (số tiền) (\"\")` để thay thế. Lưu ý rằng điều này không đảm bảo giảm thiểu các cuộc tấn công reentrancy, mà cần kết hợp với các biện pháp khác.\n\n#### Sự khác nhau giữa send(), transfer() và call.value()\n\nKhi thực hiện một giao dịch từ hợp đồng thông minh, cần phân biệt sự giống và khác giữa `someAddress.send()`, `someAddress.transfer()`, `someAddress.call().value()`.\n\n- `someAddress.send()` và `someAddress.transfer()` được coi là an toàn để chống lại reentrancy. Chúng giới hạn 2.300 gas, chỉ đủ để ghi lại một sự kiện thay vì chạy một đoạn mã khai thác.\n\n- x.transfer(y) tương đương với lệnh x.send (y), nó sẽ tự động revert nếu giao dịch thất bại.\n\n- Khác với `someAddress.send()` và `someAddress.transfer()`, `someAddress.call.value(y) `không giới hạn gas cho lời gọi và do đó hacker có thể thực thi lời gọi đến một đoạn mã độc nhằm mục đích xấu. Do đó, nó không an toàn để chống lại reentrancy.\n\nSử dụng send() hoặc transfer() sẽ ngăn chặn reentrancy nhưng nó sẽ không thích hợp với các hợp đồng mà fallback function yêu cầu hơn 2.300 gas. Chúng ta cũng có thể sử dụng someAddress.call.value(ethAmount) .gas(gasAmount) để giới hạn lượng gas cho lời gọi một cách tùy ý.\n\n#### Xử lý lỗi từ các lời gọi ngoài\n\nSolidity cung cấp các phương thức gọi mức thấp (low level) : `address.call()`, `address.callcode()`, `address.delegatecall()` và `address.send()`. Các phương thức ở mức thấp này không bao giờ ném ra ngoại lệ (throw an exception), nhưng sẽ trả về false nếu lời gọi gặp phải ngoại lệ. Mặt khác, các lời gọi hợp đồng (contract calls) (ví dụ như `ExternalContract.doSomething()`) sẽ tự động ném ra một ngoại lệ và báo lỗi.\n\nNếu bạn lựa chọn sử dụng các phương thức gọi ở mức thấp, hãy kiểm tra xem lời gọi sẽ thất bại hay thành công, bằng cách kiểm tra giá trị trả về là `true` hay` false`.\n\n```javascript\n// bad\nsomeAddress.send(55);\nsomeAddress.call.value(55)(\"\"); // this is doubly dangerous, as it will forward all remaining gas and doesn't check for result\nsomeAddress.call.value(100)(bytes4(sha3('deposit()'))); // if deposit throws an exception, the raw call() will only return false and transaction will NOT be reverted\n\n(bool success, ) = someAddress.call.value(55)(\"\");\nif(!success) {\n    // handle failure code\n}\n\nExternalContract(someAddress).deposit.value(100)();\n```\n\n#### Ưu tiên pull hơn là push cho các lời gọi ngoài\n\nCác lời gọi từ bên ngoài có thể thất bại một cách vô tình hoặc cố ý. Để giảm thiểu rủi ro từ các lỗi đó gây ra, tốt hơn hết là chia từng lời gọi thành các lời gọi nhỏ hơn. Điều này đặc biệt phù hợp với các giao dịch thanh toán, trong đó cho phép người dùng rút tiền sẽ tốt hơn là tự động chuyển tiền cho họ. (Điều này cũng làm giảm khả năng xảy ra sự cố với gasLimit.) và tránh việc thực hiện cùng một lúc nhiều hàm transfer() trong một giao dịch.\n\n```javascript\n// bad\ncontract auction {\n    address highestBidder;\n    uint highestBid;\n\n    function bid() payable {\n        require(msg.value >= highestBid);\n\n        if (highestBidder != address(0)) {\n            (bool success, ) = highestBidder.call.value(highestBid)(\"\");\n            require(success); // if this call consistently fails, no one else can bid\n        }\n\n       highestBidder = msg.sender;\n       highestBid = msg.value;\n    }\n}\n\n// good\ncontract auction {\n    address highestBidder;\n    uint highestBid;\n    mapping(address => uint) refunds;\n\n    function bid() payable external {\n        require(msg.value >= highestBid);\n\n        if (highestBidder != address(0)) {\n            refunds[highestBidder] += highestBid; // record the refund that this user can claim\n        }\n\n        highestBidder = msg.sender;\n        highestBid = msg.value;\n    }\n\n    function withdrawRefund() external {\n        uint refund = refunds[msg.sender];\n        refunds[msg.sender] = 0;\n        (bool success, ) = msg.sender.call.value(refund)(\"\");\n        require(success);\n    }\n}\n```\n\n#### Không nên dùng delegatecall với đoạn mã không được tin cậy\n\nHàm `delegatecall` được sử dụng để gọi các hàm từ các hợp đồng khác như thể chúng thuộc về hợp đồng của người gọi. Do đó, người gọi có thể thay đổi trạng thái của hợp đồng được gọi đến. Điều này có thể không an toàn. Ví dụ dưới đây cho thấy cách sử dụng `delegatecall` có thể dẫn đến việc hợp đồng bị phá hủy và mất hết số dư.\n\n```javascript\ncontract Destructor\n{\n    function doWork() external\n    {\n        selfdestruct(0);\n    }\n}\n\ncontract Worker\n{\n    function doWork(address _internalWorker) public\n    {\n        // unsafe\n        _internalWorker.delegatecall(bytes4(keccak256(\"doWork()\")));\n    }\n}\n```\n\nNếu `worker.doWork()` được gọi với tham số là địa chỉ của hợp đồng Destructor, hợp đồng Worker sẽ tự hủy. Bạn chỉ nên thực hiện delegate call cho các hợp đồng đáng tin cậy.\n\n**Lưu ý**: Đừng cho rằng các hợp đồng khi được khởi tạo có số dư bằng 0. Một kẻ tấn công có thể gửi ether đến địa chỉ của hợp đồng trước khi nó được khởi tạo. [Xem vấn đề 61](https://github.com/ConsenSys/smart-contract-best-practices/issues/61) để biết thêm chi tiết.\n\n### Ether có thể được gửi đến bất kỳ hợp đồng nào\n\nKẻ tấn công có thể gửi ether đến bất kỳ tài khoản nào và điều này không thể ngăn chặn được (ngay cả với fallback function với câu lệnh revert).\n\nKẻ tấn công có thể làm điều này bằng cách tạo ra một hợp đồng, gửi cho nó 1 wei và hàm `selfdestruct(victimAddress`), ở đây `victimAddress` là địa chỉ hợp đồng cần gửi ether vào.\n\n### Hãy nhớ rằng Ethereum là mạng public blockchain, mọi dữ liệu trên các block đều được công khai\n\nNhiều ứng dụng yêu cầu dữ liệu được gửi phải ở chế độ riêng tư cho đến một lúc nào đó. Các trò chơi (ví dụ: oản tù tì) và việc đấu giá kín là hai ví dụ chính. Nếu bạn đang xây dựng một ứng dụng mà sự riêng tư là một vấn đề, hãy đảm bảo bạn tránh yêu cầu người dùng công khai thông tin quá sớm. Chiến lược tốt nhất là chia thành các giai đoạn riêng biệt: đầu tiên thì sử dụng hàm băm của các giá trị và trong giai đoạn tiếp theo thì tiết lộ các giá trị.\n\nVí dụ:\n\n- Trong trò chơi oản tù tì, yêu cầu cả hai người chơi gửi giá trị băm của kéo, đá hay giấy (do người chơi quyết định), sau đó trò chơi yêu cầu cả hai người chơi gửi kết quả mình lựa chọn. Tiếp đó so sánh giá trị băm, nếu khớp thì hợp lệ, trò chơi sẽ phân thắng hòa hay thua dựa trên kết quả chọn của 2 người chơi.\n\n- Trong phiên đấu giá kín, yêu cầu người đấu giá gửi giá trị băm mức giá mà họ chọn trong giai đoạn ban đầu (cùng với khoản tiền gửi lớn hơn giá trị giá thầu của họ), sau đó gửi giá trị đấu giá của họ trong giai đoạn thứ hai.\n\n- Khi phát triển một ứng dụng mang tính ngẫu nhiên, thứ tự phải luôn là: (1) người chơi submit, (2) số ngẫu nhiên được tạo, (3) người chơi hoàn thành giao dịch. Phương thức mà các số ngẫu nhiên được tạo ra là cả một lĩnh vực nghiên cứu, các giải pháp tốt nhất hiện tại bao gồm việc sử dụng block header Bitcoin (được xác minh thông qua http://btcrelay.org), các cơ chế hash-commit-reveal (tức là một bên tạo ra một số, xuất bản hàm băm của nó để \"cam kết\" và sau đó tiết lộ giá trị sau), cùng với đó là [RANDAO](https://github.com/randao/randao). Vì Ethereum là một giao thức xác định, không có biến nào trong giao thức có thể được sử dụng như một số ngẫu nhiên không thể đoán trước. Ngoài ra, hãy lưu ý rằng thợ đào (miner) trong một chừng mực nào đó kiểm soát giá trị block.blockhash().\n\n### Cảnh giác với khả năng một số người tham gia có thể \"drop offline\" và không quay lại\n\nVí dụ, trong trò chơi oản tù tì, một ván đấu được tiếp tục cho đến khi cả hai người chơi gửi lựa chọn của họ. Tuy nhiên, một người chơi có thể không bao giờ gửi lựa chọn của họ - thực tế, nếu một người chơi thấy động thái được tiết lộ từ người chơi khác và xác định rằng họ đã thua, họ không có lý do gì để tự gửi kết quả. Khi gặp các tình huống như vậy thì , (1) cung cấp một cách để tránh những người chơi không tham gia, có thể giới hạn thời gian và (2) xem xét thêm lợi ích bổ sung cho những người tham gia khi gửi kết quả trong tất cả các tình huống.\n\n### Trường hợp đổi dấu số âm bé nhất\n\nSolidity cung cấp một số kiểu dữ liệu số nguyên. Giống như trong hầu hết các ngôn ngữ lập trình khác, trong Solidity, một số nguyên N bit có thể biểu thị các giá trị từ `-2 ^ (N-1) đến 2 ^ (N-1) - 1`. Điều này có nghĩa là không có giá trị dương mà có trị tuyệt đối bằng `MIN_INT`. `- MIN_INT` sẽ được gắn bằng `MIN_INT`.\n\nĐiều này đúng với tất cả các kiểu số nguyên trong Solidity (int8, int16, ..., int256).\n\n```javascript\ncontract Negation {\n    function negate8(int8 _i) public pure returns(int8) {\n        return -_i;\n    }\n\n    function negate16(int16 _i) public pure returns(int16) {\n        return -_i;\n    }\n\n    int8 public a = negate8(-128); // -128\n    int16 public b = negate16(-128); // 128\n    int16 public c = negate16(-32768); // -32768\n}\n}\n\n```\n\nMột cách để xử lý điều này là kiểm tra giá trị của biến trước khi đảo dấu và ném ra ngoại lệ nếu nó bằng `MIN_INT`. Một tùy chọn khác là đảm bảo rằng số âm nhất bé nhất sẽ không bao giờ đạt được bằng cách sử kiểu biến có khoảng giá trị lớn (ví dụ: int32 thay vì int16).\n\n### Sử dụng assert(), revert() và require() đúng cách\n\nCác hàm assert và require được sử dụng để kiểm tra các điều kiện và ném ra một ngoại lệ nếu điều kiện không được đáp ứng.\n\nHàm `assert` chỉ nên được sử dụng để kiểm tra các lỗi bên trong (internal error) và các biến hằng.\n\nHàm `require` nên được dùng để đảm bảo các điều kiện hợp lệ, chẳng hạn như biến đầu vào, biến trạng thái của hợp đồng hoặc để xác thực giá trị trả về từ các lời gọi đến hợp đồng bên ngoài.\n\nVí dụ dưới đây cho thấy rằng các opcode không hợp lệ không có cơ hội để thực thi: các biến đều được xác minh và nếu có sai số thì đoạn mã sẽ ném ra lỗi.\n\n```javascript\npragma solidity ^0.5.0;\n\ncontract Sharer {\n    function sendHalf(address payable addr) public payable returns (uint balance) {\n        require(msg.value % 2 == 0, \"Even value required.\"); //Require() can have an optional message string\n        uint balanceBeforeTransfer = address(this).balance;\n        addr.transfer(msg.value / 2);\n        // Since transfer throws an exception on failure and\n        // cannot call back here, there should be no way for us to\n        // still have half of the money.\n        assert(address(this).balance == balanceBeforeTransfer - msg.value / 2); // used for internal error checking\n        return address(this).balance;\n    }\n}\n```\n\n### Chỉ sử modifier khi cần kiểm tra dữ liệu\n\nMã bên trong modifier được thực thi trước khi chạy mã bên trong hàm. Do đó, bất kỳ thay đổi trạng thái hoặc lời gọi ngoài nào được tạo ra bởi đoạn mã trong modifier cũng sẽ vi phạm thiết kế [Checks-Effects-Interactions](https://solidity.readthedocs.io/en/develop/security-considerations.html#use-the-checks-effects-interactions-pattern) mà chúng tôi đã đề ra. Ví dụ dưới đây, một lời gọi ngoài hợp đồng được chèn trong modifier có thể dẫn đến lỗ hổng reentrancy.\n\n```javascript\ncontract Registry {\n    address owner;\n\n    function isVoter(address _addr) external returns(bool) {\n        // Code\n    }\n}\n\ncontract Election {\n    Registry registry;\n\n    modifier isEligible(address _addr) {\n        require(registry.isVoter(_addr));\n        _;\n    }\n\n    function vote() isEligible(msg.sender) public {\n        // Code\n    }\n}\n```\n\nTrong trường hợp này, hợp đồng Registry có thể bị tấn công reentracy bằng cách gọi đến Election.vote()\n\n**Lưu ý**: Sử dụng modifier để thay các câu lệnh kiểm tra điều kiện bên trong thân của hàm. Điều này làm cho mã nguồn hợp đồng thông minh của bạn gọn nhẹ và dễ đọc hơn.\n\n### Hãy cẩn thận với việc làm tròn kết quả trong phép chia\n\nTất cả các phép chia số nguyên được làm tròn bằng cách lấy số nguyên gần nhất. Nếu bạn cần độ chính xác cao hơn, hãy cân nhắc lưu trữ cả tử và mẫu số, hoặc số nhân vào một biến trung gian nào đó.\n\n(Trong tương lai, Solidity sẽ có [fixed_point type](https://solidity.readthedocs.io/en/develop/types.html#fixed-point-numbers), điều này sẽ khiến vấn đề dễ dàng hơn.)\n\n```javascript\n// bad\nuint x = 5 / 2; // Result is 2, all integer divison rounds DOWN to the nearest integer\n```\n\nSử dụng số nhân sẽ ngăn việc làm tròn xuống, số nhân này cần được tính toán khi làm việc với x trong tương lai:\n\n```javascript\n// good\nuint multiplier = 10;\nuint x = (5 * multiplier) / 2;\n```\n\nLưu trữ tử số và mẫu số có nghĩa là bạn có thể tính kết quả của tử số/mẫu số ngoài chuỗi:\n\n```javascript\n// good\nuint numerator = 5;\nuint denominator = 2;\n```\n\n### Abstract contract và interfaces\n\nCả interface và hợp đồng trừu tượng (abstract contract) đều có chung một tư tưởng là cho phép tùy chỉnh mã nguồn của các function dựa trên prototype có sẵn. Interface, được giới thiệu trong phiên bản Solidity 0.4.11, tương tự như các abstract contract nhưng interface chỉ có các prototype mà không có chứa thân hàm. Interface cũng có những hạn chế như không thể truy cập vào storage hoặc kế thừa từ các interface khác, điều này làm cho các abstract contract có ưu thế hơn một chút. Ngoài ra, điều quan trọng cần lưu ý là nếu một hợp đồng kế thừa từ một abstract contract thì các hàm sẽ được thực thi bằng cách ghi đè (overriding).\n\n### Fallback functions\n\n#### Giữ cho Fallback function đơn giản\n\n[Fallback function](https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function) được thực thi khi hợp đồng được gọi bởi một message không có tham số (hoặc message đó gọi đến một hàm không tồn tại trong hợp đồng). Nếu bạn chỉ muốn nhận Ether từ fallback function bằng cách gọi `.send()` hoặc `.transfer()`, thì 2300 gas đủ để cho bạn kích hoạt một event. Nếu cần sử nhiều tính toán hơn thì có thể cấu hình lượng gas tối đa mà fallback function có thể sử dụng.\n\n```javascript\n// bad\nfunction() payable { balances[msg.sender] += msg.value; }\n\n// good\nfunction deposit() payable external { balances[msg.sender] += msg.value; }\n\nfunction() payable { require(msg.data.length == 0); emit LogDepositReceived(msg.sender); }\n```\n\n### Kiểm tra độ dài dữ liệu trong fallback function\n\nFallback function không chỉ được dùng để nhận ether gửi vào hợp đồng (không có dữ liệu trong message) mà còn dùng kh gọi hàm không có trong hợp đồng hoặc tham số không đúng. Do đó, kiểm tra độ dài data trước khi thực thi các mã trong fallback function nhằm tránh việc bị thực thi mã độc.\n\n```javascript\n// bad\nfunction() payable { emit LogDepositReceived(msg.sender); }\n\n// good\nfunction() payable { require(msg.data.length == 0); emit LogDepositReceived(msg.sender); }\n```\n\n### Định nghĩa rõ ràng các hàm  và các biến có thể nhận ether\n\nBắt đầu từ phiên bản Solidity 0.4.0, mọi hàm nhận ether phải có modifier `payable`, mặt khác, nếu lời gọi đến hàm payable có msg.value = 0 thì giao dịch sẽ bị revert ([trừ khi bị bắt buộc](https://consensys.github.io/smart-contract-best-practices/recommendations/#remember-that-ether-can-be-forcibly-sent-to-an-account)).\n\nNếu bạn muốn dùng chức năng chuyển tiền, hãy khai báo các biến và các tham số của hàm có dạng `address payable`. Bạn chỉ có thể sử dụng .transfer (..) và .send (..) trên `address payable` thay vì `address`. Bạn có thể sử dụng .call (..) cho cả `address payable` và `address`. Nhưng điều này không được khuyến khích.\n\n**Lưu ý**: Modifier payable chỉ áp dụng cho các lời gọi từ bên ngoài. Nếu một hàm non-payable gọi hàm payable trên cùng một hợp đồng, thì hàm non-payable sẽ không thành công, mặc dù msg.value vẫn được đặt.\n\n### Định nghĩa rõ ràng phạm vi truy cập của các hàm, các biến\n\nCác hàm có bốn loại phạm vi truy cập là external, public, private, internal. . Đối với các biến, không thể định nghĩa phạm vi external. Định nghĩa đầy đủ, rõ ràng phạm vi truy cập của các biến, các hàm giúp dễ dàng nắm được được phạm vi của từng thành phần trong hợp đồng, tránh các lỗi không đáng có.\n\n- Các hàm `external` là một phần chức năng của contract interface. Các hàm external hiểu quả hơn các hàm public khi tham số là các mảng dữ liệu lớn do hàm external sẽ tốn ít gas hơn.\n- Các hàm `public` có thể được gọi từ bất cứ đâu, trong hợp đồng, hoặc từ một hợp đồng khác.\n- Các hàm `internal` chỉ có thể được gọi từ bên trong hợp đồng hoặc các hợp đồng kế thừa.\n- Các hàm `private` chỉ có thể được gọi từ bên trong hợp đồng.\n\n```javascript\n// bad\nuint x; // the default is internal for state variables, but it should be made explicit\nfunction buy() { // the default is public\n    // public code\n}\n\n// good\nuint private y;\nfunction buy() external {\n    // only callable externally or using this.buy()\n}\n\nfunction utility() public {\n    // callable externally, as well as internally: changing this code requires thinking about both cases.\n}\n\nfunction internalAction() internal {\n    // internal code\n}\n```\n\n### Fix cứng phiên bản trình biên dịch của Solidity\n\nCác hợp đồng nên được triển khai với cùng phiên bản trình biên dịch mà chúng đã được kiểm thử nhiều nhất. Fix cứng phiên bản trình biên dịch để tránh trường hợp được triển khai bởi một phiên bản mới hơn (vốn có thể tiềm ẩn lỗi).\n\n```\n// bad\npragma solidity ^0.4.4;\n\n// good\npragma solidity 0.4.4;\n```\n\n### Sử dụng các sự kiện (event) để theo dõi hoạt động của hợp đồng\n\nCần có cách giám sát hoạt động của hợp đồng sau khi nó được triển khai. Một cách để thực hiện điều này là xem xét tất cả các giao dịch của hợp đồng, tuy nhiên điều đó là chưa đủ, vì các lời gọi (message call) giữa các hợp đồng không được ghi lại trên blockchain. Hơn nữa, nó cũng chỉ hiển thị các tham số đầu vào, không phải là những thay đổi trạng thái. Ngoài việc theo dõi hoạt động của hợp đồng ra, các sự kiện có thể được sử dụng để tương tác với giao diện người dùng.\n\n```javascript\ncontract Charity {\n    mapping(address => uint) balances;\n\n    function donate() payable public {\n        balances[msg.sender] += msg.value;\n    }\n}\n\ncontract Game {\n    function buyCoins() payable public {\n        // 5% goes to charity\n        charity.donate.value(msg.value / 20)();\n    }\n}\n```\n\nỞ trên, hợp đồng Game sẽ thực hiện lời gọi (internal call) đến Charity.donate(). Giao dịch này sẽ không xuất hiện trong danh sách các giao dịch bên ngoài (external transaction) của hợp đồng Charity mà có trong danh sách các giao dịch nội bộ (internal transaction).\n\nSự kiện là cách thuận tiện để ghi lại một điều gì đó đã xảy ra trong hợp đồng. Các sự kiện được phát ra (emit) được lưu lại trong blockchain cùng với dữ liệu khác của hợp đồng. Đây là một cải tiến cho ví dụ ở trên, chúng ta sử dụng sự kiện để ghi lại lịch sử quyên góp của Hội từ thiện.\n\n```javascript\ncontract Charity {\n    // define event\n    event LogDonate(uint _amount);\n\n    mapping(address => uint) balances;\n\n    function donate() payable public {\n        balances[msg.sender] += msg.value;\n        // emit event\n        emit LogDonate(msg.value);\n    }\n}\n\ncontract Game {\n    function buyCoins() payable public {\n        // 5% goes to charity\n        charity.donate.value(msg.value / 20)();\n    }\n}\n```\n\nTất cả các giao dịch gọi hàm donate của hợp đồng Charity, dù trực tiếp hay không, sẽ hiển thị trong danh sách sự kiện của hợp đồng đó cùng với số tiền quyên góp.\n\n### Sự phức tạp của ngôn từ (Lườm rau gắp thịt)\n\nKhi bạn định nghĩa tên một hàm, nếu nó trùng với tên các hàm có sẵn của Solidity. Nó sẽ ghi đè (override) hàm mặc định nhưng nó sẽ gây hiểu nhầm cho người đọc với ý nghĩa của đoạn mã.\n\n```javascript\ncontract PretendingToRevert {\n    function revert() internal constant {}\n}\n\ncontract ExampleContract is PretendingToRevert {\n    function somethingBad() public {\n        revert();\n    }\n}\n```\n\n```javascript\ncontract FakingItsOwnDeath {\n    function selfdestruct(address x) internal constant {}\n}\n\ncontract SelfDestructive is FakingItsOwnDeath {\n    function die() public {\n        selfdestruct(address(0x0));\n    }\n}\n```\n\nỞ ví dụ thứ nhất, hàm `revert()` được gọi là hàm revert của hợp đồng `PretendingToRevert` thay vì hàm `revert()` mặc định. Do đó, khi gọi hàm `someThingBad()` của Example thì nó vẫn hoạt động bình thường.\n\nTương tự ở ví dụ thứ hai, không có hợp đồng nào bị hủy cả khi gọi đến hàm `die()` của SelfDestructive.\n\n### Tránh sử dụng tx.origin\n\ntx.origin chỉ có thể là tài khoản người dùng, không thể là tài khoản hợp đồng.\nmsg.sender có thể là tài khoản người dùng hoặc tài khoản hợp đồng.\n\nVí dụ các lời gọi theo chuỗi như sau: A->B->C->D, một hàm của hợp đồng D được gọi thì msg.sender là địa chỉ của C còn tx.origin là địa chỉ của A.\n\n```javascript\ncontract MyContract {\n\n    address owner;\n\n    function MyContract() public {\n        owner = msg.sender;\n    }\n\n    function sendTo(address receiver, uint amount) public {\n        require(tx.origin == owner);\n        receiver.transfer(amount);\n    }\n\n}\n\ncontract AttackingContract {\n\n    MyContract myContract;\n    address attacker;\n\n    function AttackingContract(address myContractAddress) public {\n        myContract = MyContract(myContractAddress);\n        attacker = msg.sender;\n    }\n\n    function() public {\n        myContract.sendTo(attacker, msg.sender.balance);\n    }\n\n}\n```\n\nĐoạn mã ở trên tận dụng đặc điểm của `tx.orign` để chuyển tiền từ hợp đồng `MyContract` vào tài khoản của kẻ xấu bằng cách viết hợp đồng `AttackingContract`và gọi đến hàm `sendTo` trong `MyContract`.\n\nKhả năng trong tương lai, `tx.origin` sẽ bị loại bỏ khỏi nền tảng Ethereum. Chính nhà đồng sáng lập Ethereum Vatalik Buterin cho rằng tx.orgin không có ý nghĩa để có thể sử dụng trong hợp đồng thông minh.\n\nĐiều đáng nói là bằng cách sử dụng tx.origin, bạn sẽ hạn chế khả năng tương tác giữa các hợp đồng vì hợp đồng sử dụng tx.origin không thể được sử dụng bởi một hợp đồng khác vì tài khoản hợp đồng không thể là tx.origin.\n\n### Nhãn thời gian (timestamp)\n\nCó ba điều cần lưu ý khi sử dụng nhãn thời gian để thực hiện các chức năng quan trọng trong hợp đồng thông minh, đặc biệt là khi các hành động liên có quan đến việc chuyển tiền.\n\n#### Thao tác với nhãn thời gian\n\nCần lưu ý rằng nhãn thời gian của một block có thể được tác động bởi thợ đào. Chúng ta cùng xem xét ví dụ sau đây:\n\n```javascript\nuint256 constant private salt =  block.timestamp;\n\nfunction random(uint Max) constant private returns (uint256 result){\n    //get the best seed for randomness\n    uint256 x = salt * 100/Max;\n    uint256 y = salt * block.number/(salt % 5) ;\n    uint256 seed = block.number/3 + (salt % 300) + Last_Payout + y;\n    uint256 h = uint256(block.blockhash(seed));\n\n    return uint256((h / x)) % Max + 1; //random number between 1 and Max\n}\n```\n\nKhi hợp đồng sử dụng nhãn thời gian để tạo số ngẫu nhiên, người thợ đào thực sự có thể đóng nhãn thời gian trong vòng 15 giây khi block đang được xác thực, cho phép người thợ đào có thể tính toán trước các tùy chọn. Nhãn thời gian không phải là ngẫu nhiên và không nên được sử dụng trong bối cảnh đó.\n\n#### Quy tắc 15 giây\n\nTrong Yellow Paper của Ethereum không mô tả về số lượng block có thể tạo ra trong một khoảng thời gian nhất định, nhưng nó đề cập rằng mỗi nhãn thời gian của block con phải lớn hơn nhãn thời gian của block cha mẹ. Các giao thức Ethereum trên Geth và Parity đều từ chối các block với nhãn thời gian lớn hơn 15 giây so với cha mẹ nó. Do đó, một nguyên tắc nhỏ trong việc đánh giá việc sử dụng nhãn thời gian là:\n\n**Nếu sự kiện hợp đồng bạn triển khai có thể thay đổi trong 15 giây và duy trì tính toàn vẹn, thì việc sử dụng block.timestamp là an toàn.**\n\n#### Tránh sử dụng block.number như là nhãn thời gian\n\nCó thể ước tính một khoảng thời gian bằng cách sử dụng thuộc tính block.number và [thời gian khối trung bình](https://etherscan.io/chart/blocktime), tuy nhiên đây không phải là cách hay vì thời gian một block mới được tạo mới (block times) có thể thay đổi (ví dụ như việc xảy ra [fork reorganisations](https://blog.ethereum.org/2015/08/08/chain-reorganisation-depth-expectations/) hoặc thay đổi [difficulty bomb](https://github.com/ethereum/EIPs/issues/649)).\n\n### Hãy thận trọng khi sử dụng tính năng đa kế thừa\n\nKhi sử dụng đa kế thừa trong Solidity, điều quan trọng là phải hiểu cách nó hoạt động như thế nào.\n\n```javascript\ncontract Final {\n    uint public a;\n    function Final(uint f) public {\n        a = f;\n    }\n}\n\ncontract B is Final {\n    int public fee;\n\n    function B(uint f) Final(f) public {\n    }\n    function setFee() public {\n        fee = 3;\n    }\n}\n\ncontract C is Final {\n    int public fee;\n\n    function C(uint f) Final(f) public {\n    }\n    function setFee() public {\n        fee = 5;\n    }\n}\n\ncontract A is B, C {\n  function A() public B(3) C(5) {\n      setFee();\n  }\n}\n```\n\nKhi một hợp đồng được triển khai, trình biên dịch sẽ tuyến tính hóa sự kế thừa từ phải sang trái (sau từ khóa `is` là danh sách các hợp đồng cha mẹ được liệt kê).\n\n#### Final \\<- B \\<- C \\<- A\n\nHàm khởi tạo của hợp đồng A sẽ trả về 5, vì C là gần A nhất theo sự tuyết tính hóa từ phải qua trái.\n\nĐể biết thêm về bảo mật và kế thừa, hãy xem [bài viết này](https://pdaian.com/blog/solidity-anti-patterns-fun-with-inheritance-dag-abuse/)\n\nĐể giúp đóng góp, Github của Solidity có một [dự án](https://github.com/ethereum/solidity/projects/9#card-8027020) với tất cả các vấn đề liên quan đến thừa kế.\n\n### Sử dụng interface thay vì address\n\nKhi một hàm có tham số đầu vào là địa chỉ của một hợp đồng, tốt hơn là nên truyền vào interface hoặc một tham chiếu đến hợp đồng đó thay vì truyền vào địa chỉ của hợp đồng.\n\n```javascript\ncontract Validator {\n    function validate(uint) external returns(bool);\n}\n\ncontract TypeSafeAuction {\n    // good\n    function validateBet(Validator _validator, uint _value) internal returns(bool) {\n        bool valid = _validator.validate(_value);\n        return valid;\n    }\n}\n\ncontract TypeUnsafeAuction {\n    // bad\n    function validateBet(address _addr, uint _value) internal returns(bool) {\n        Validator validator = Validator(_addr);\n        bool valid = validator.validate(_value);\n        return valid;\n    }\n}\n```\n\nNhững lợi ích của việc sử dụng hợp đồng `TypeSafeAuction` ở trên có thể được nhìn thấy từ ví dụ dưới đây. Nếu hàm `validateBet()` có tham số đầu vào là địa chỉ của hợp đồng, hoặc tham chiếu của một hợp đồng không phải là `TypeSafeAuction` thì trình biên dịch ném ra lỗi.\n\n```javascript\ncontract NonValidator{}\n\ncontract Auction is TypeSafeAuction {\n    NonValidator nonValidator;\n\n    function bet(uint _value) {\n        bool valid = validateBet(nonValidator, _value); // TypeError: Invalid type for argument in function call.\n                                                        // Invalid implicit conversion from contract NonValidator\n                                                        // to contract Validator requested.\n    }\n}\n```\n\n### Tránh sử dụng extcodesize để kiểm tra tài khoản người dùng (Externally Owned Accounts)\n\nModifier dưới đây có chức năng kiểm tra xem message gọi đến là tài khoản hợp đồng hay tài khoản người dùng.\n\n```javascript\n// bad\nmodifier isNotContract(address _a) {\n  uint size;\n  assembly {\n    size := extcodesize(_a)\n  }\n    require(size == 0);\n     _;\n}\n```\n\nÝ tưởng rất đơn giản: nếu một địa chỉ có chứa mã nguồn, đó không phải là tài khoản người dùng mà là tài khoản hợp đồng. Tuy nhiên, một hợp đồng sẽ chưa bao gồm mã nguồn trong quá trình khởi tạo. Điều này có nghĩa là trong khi hàm contructor của hợp đồng đang được thực hiện, nó có thể thực hiện các lời gọi đến các hợp đồng khác với `extcodesize` trả về 0. Dưới đây là một ví dụ để làm rõ hơn.\n\n```javascript\ncontract OnlyForEOA {    \n    uint public flag;\n\n    // bad\n    modifier isNotContract(address _a){\n        uint len;\n        assembly { len := extcodesize(_a) }\n        require(len == 0);\n        _;\n    }\n\n    function setFlag(uint i) public isNotContract(msg.sender){\n        flag = i;\n    }\n}\n\ncontract FakeEOA {\n    constructor(address _a) public {\n        OnlyForEOA c = OnlyForEOA(_a);\n        c.setFlag(1);\n    }\n}\n```\n\nĐoạn mã trong hàm contructor của `FakeEOA` gọi đến hàm `setFlag` của `OnlyForEOA`, do hàm constructor của hợp đồng `FakeEOA` chưa được thực hiện xong, nên extcodesize của nó sẽ trả về 0 và vượt qua được bộ lọc của modifier `isNotContract` từ đó thay đổi giá trị flag trong` OnlyForEOA` một cách trái phép.\n\n**Cảnh báo**\\*:\nNếu mục tiêu của bạn là ngăn chặn các hợp đồng khác có thể gọi đến hợp đồng của bạn, thì việc dùng `extcodesize` có lẽ cũng là tương đối tốt. Một cách tiếp cận khác là kiểm tra giá trị của `(tx.origin == msg.sender)`, mặc dù điều này cũng có nhược điểm.\n\n### Cẩn thận với phép chia cho 0 (Sodility \\<0,4)\n\nTrước phiên bản 0.4, Solidity [trả về 0](https://github.com/ethereum/solidity/issues/670) và không ném ngoại lệ khi một số được chia cho 0. Đảm bảo bạn đang chạy phiên bản solidity từ 0.4 trở lên.\n\n### Cách đặt tên function và event (Solidity \\<0.4.21)\n\nViết in hoa chữ đầu tiên tên của event, để ngăn ngừa rủi ro nhầm lẫn giữa các function và event. Đối với các function, luôn luôn bắt đầu bằng một chữ cái viết thường, ngoại trừ hàm khởi tạo (constructor).\n\n<a name=\"known-attacks\"></a>\n\n# Hiểu về các phương thức tấn công phổ biến\n\nBiết tấn công để biết cách phòng thủ là một trong những nguyên tắc cơ bản trong an toàn thông tin. Nội dung phần này đề cập đến các lỗ hổng, phương thức tấn công đã biết để có thể khai thác hợp đồng thông minh.\n\n## Reentrancy\n\nMột trong những mối nguy hiểm lớn khi gọi đến các hợp đồng bên ngoài là chúng có thể chiếm quyền điều khiển và thực hiện các thay đổi không mong muốn. Loại lỗi này có thể có nhiều biến thể và cả hai lỗi lớn dẫn vụ DAO hack nổi tiếng đều là các lỗi thuộc loại này.\n\n### Reentrancy trên một hàm (Reentrancy on single function)\n\n```javascript\n// INSECURE\nmapping (address => uint) private userBalances;\n\nfunction withdrawBalance() public {\n    uint amountToWithdraw = userBalances[msg.sender];\n    (bool success, ) = msg.sender.call.value(amountToWithdraw)(\"\"); // At this point, the caller's code is executed, and can call withdrawBalance again\n    require(success);\n    userBalances[msg.sender] = 0;\n}\n```\n\nVì số dư tài khoản của người dùng không gắn bằng 0 cho đến khi kết thúc hàm, hacker có thể lợi dụng điều này để rút tiền nhiều lần bằng cách gọi liên tục hàm withdrawBalance để ngăn cản hàm đó chạy đến câu lệnh `userBalances[msg.sender] = 0; `\n\n> DAO (Decentralized Autonomous Organization). Mục đích mà nó hướng đến là tự động hóa các quy tắc, bộ máy điều hành của một các tổ chức, từ đó loại bỏ vai trò của tài liệu và con người trong quá trình quản lý, tạo ra một cấu trúc với sự kiểm soát phi tập trung.\n>\n> Vào ngày 17 tháng 6 năm 2016, DAO đã bị hack và 3,6 triệu Ether (50 triệu đô la) đã bị đánh cắp bằng cách khai thác lỗ hổng Reetrancy.\n>\n> Ethereum Foundation đã phát hành một bản cập nhật quan trọng để khôi phục lại trạng thái trước vụ hack. Điều này dẫn đến việc Ethereum được chia thành Ethereum Classic và Ethereum.\n\nTrong ví dụ trên, cách giảm thiểu tối đa rủi ro là sử dụng  hàm `send()` thay vì hàm `call.value ()`. Điều này sẽ hạn chế bất kỳ mã bên ngoài nào được thực thi.\n\nTuy nhiên, nếu bạn không thể tránh các lời gọi ngoài, thì cách đơn giản để ngăn chặn cuộc tấn công này là đảm bảo bạn không gọi thực hiện lời gọingoài trước khi các đoạn mã internal được thực hiện xong.\n\n```javascript\nmapping (address => uint) private userBalances;\n\nfunction withdrawBalance() public {\n    uint amountToWithdraw = userBalances[msg.sender];\n    userBalances[msg.sender] = 0;\n    (bool success, ) = msg.sender.call.value(amountToWithdraw)(\"\"); // The user's balance is already 0, so future invocations won't withdraw anything\n    require(success);\n}\n```\n\n### Reentrancy liên hàm (Cross-function Reentrancy)\n\nKẻ tấn công cũng có thể thực hiện một cuộc tấn công bằng cách sử dụng hai hay nhiều hàm khác nhau có cùng trạng thái.\n\n```javascript\n// INSECURE\nmapping (address => uint) private userBalances;\n\nfunction transfer(address to, uint amount) {\n    if (userBalances[msg.sender] >= amount) {\n       userBalances[to] += amount;\n       userBalances[msg.sender] -= amount;\n    }\n}\n\nfunction withdrawBalance() public {\n    uint amountToWithdraw = userBalances[msg.sender];\n    (bool success, ) = msg.sender.call.value(amountToWithdraw)(\"\"); // At this point, the caller's code is executed, and can call transfer()\n    require(success);\n    userBalances[msg.sender] = 0;\n}\n```\n\nTrong trường hợp này, kẻ tấn công sẽ gọi hàm transfer() khi chúng đang thực hiện lời gọi ngoài `.call.value(amountToWithdraw)(\"\")` ở hàm `withdrawBalance`. Vì khi đó số dư của kẻ tấn công chưa được gán bằng 0, nên chúng có thể chuyển mã số dư đến một tài khoản khác mặc dù chúng đã nhận được tiền từ hàm withdrawBalance. Lỗ hổng này cũng đa được sử dụng trong cuộc tấn công vào DAO.\n\nLưu ý rằng trong ví dụ này, cả hai hàm đều cùng thuộc một hợp đồng. Tuy nhiên, lỗi có thể xảy ra trên nhiều hợp đồng, nếu các hợp đồng đó chia sẻ trạng thái với nhau.\n\n### Pitfalls in Reentrancy Solutions\n\nReentrancy có thể xảy ra trên một chuỗi các hàm, thậm chí là chuỗi các hợp đồng. Cho nên, bất kỳ giải pháp nào nhằm ngăn chặn reentrancy chỉ với một hàm là không đủ.\n\nThay vào đó, chúng tôi khuyến nghị nên chạy hết các câu lệnh trong hợp đồng (internal work)  (ví dụ: thay đổi trạng thái các biến, mapping) trước việc thực hiện các lời gọi hàm bên ngoài (external call). Quy tắc này, nếu được tuân thủ cẩn thận, sẽ phòng chống được các lỗ hổng do reentrancy có thể gây ra. Tuy nhiên, bạn không chỉ cần tránh các lời gọi ngoài được thực thi quá sớm mà còn nên tránh việc các hàm bên trong hợp đồng gọi đến các hàm khác quá sớm (nên để các lời gọi hàm thực thi sau khi các đoạn mã logic khác trong thân hàm đã chạy qua). Ví dụ sau đây minh chứng cho việc viết mã không an toàn.\n\n```javascript\n// INSECURE\nmapping (address => uint) private userBalances;\nmapping (address => bool) private claimedBonus;\nmapping (address => uint) private rewardsForA;\n\nfunction withdrawReward(address recipient) public {\n    uint amountToWithdraw = rewardsForA[recipient];\n    rewardsForA[recipient] = 0;\n    (bool success, ) = recipient.call.value(amountToWithdraw)(\"\");\n    require(success);\n}\n\nfunction getFirstWithdrawalBonus(address recipient) public {\n    require(!claimedBonus[recipient]); // Each recipient should only be able to claim the bonus once\n\n    rewardsForA[recipient] += 100;\n    withdrawReward(recipient); // At this point, the caller will be able to execute getFirstWithdrawalBonus again.\n    claimedBonus[recipient] = true;\n}\n```\n\nMặc dù hàm `getFirstWithdrawalBonus()` không gọi thực hiện lời gọi ngoài, nhưng đoạn mã `withdrawReward(recipient)` gọi đến hàm `withdrawReward()` đã tạo ra lỗ hổng mà kẻ xấu có thể khai thác. Do đó, phải xem lời gọi đến hàm `withdrawReward()` trong hàm `getFirtWithdrawBonus()` là không đáng tin cậy và nên để nó được thực thi ở sau cùng trong hàm `getFirtWithdrawBonus()`.\n\n```javascript\nmapping (address => uint) private userBalances;\nmapping (address => bool) private claimedBonus;\nmapping (address => uint) private rewardsForA;\n\nfunction untrustedWithdrawReward(address recipient) public {\n    uint amountToWithdraw = rewardsForA[recipient];\n    rewardsForA[recipient] = 0;\n    (bool success, ) = recipient.call.value(amountToWithdraw)(\"\");\n    require(success);\n}\n\nfunction untrustedGetFirstWithdrawalBonus(address recipient) public {\n    require(!claimedBonus[recipient]); // Each recipient should only be able to claim the bonus once\n\n    claimedBonus[recipient] = true;\n    rewardsForA[recipient] += 100;\n    untrustedWithdrawReward(recipient); // claimedBonus has been set to true, so reentry is impossible\n}\n```\n\nNgoài việc chuyển dòng code gọi đến hàm withdrawReward xuống cuối cùng trong hàm GetFirstWithdrawalBonus, chúng ta còn nên thay đổi tên hàm để đánh dấu nó là không đáng tin cậy.\n\nMột giải pháp khác được đề xuất là [mutex](https://en.wikipedia.org/wiki/Mutual_exclusion). Điều này cho phép bạn \"khóa\" một số trạng thái để chủ sở hữu khóa mới có thể thay đổi trạng thái. Một ví dụ đơn giản có thể trông như thế này:\n\n```javascript\n// Note: This is a rudimentary example, and mutexes are particularly useful where there is substantial logic and/or shared state\nmapping (address => uint) private balances;\nbool private lockBalances;\n\nfunction deposit() payable public returns (bool) {\n    require(!lockBalances);\n    lockBalances = true;\n    balances[msg.sender] += msg.value;\n    lockBalances = false;\n    return true;\n}\n\nfunction withdraw(uint amount) payable public returns (bool) {\n    require(!lockBalances && amount > 0 && balances[msg.sender] >= amount);\n    lockBalances = true;\n\n    (bool success, ) = msg.sender.call(amount)(\"\");\n\n    if (success) { // Normally insecure, but the mutex saves it\n      balances[msg.sender] -= amount;\n    }\n\n    lockBalances = false;\n    return true;\n}\n```\n\nNếu kẻ xấu cố gắng gọi hàm withdraw() một lần nữa trước khi câu lệnh `msg.sender.call(amount)()` kết thúc, khóa sẽ ngăn cản điều đó. Đây có thể là một giải pháp hiệu quả, nhưng nó trở nên khó khăn khi bạn có nhiều hợp đồng liên kết với nhau. Sau đây ví dụ minh chứng cho nhận định trên:\n\n```javascript\n// INSECURE\ncontract StateHolder {\n    uint private n;\n    address private lockHolder;\n\n    function getLock() {\n        require(lockHolder == address(0));\n        lockHolder = msg.sender;\n    }\n\n    function releaseLock() {\n        require(msg.sender == lockHolder);\n        lockHolder = address(0);\n    }\n\n    function set(uint newState) {\n        require(msg.sender == lockHolder);\n        n = newState;\n    }\n}\n```\n\nKẻ tấn công có thể gọi hàm getLock(), và sẽ không bao giờ gọi đến releaseLock(). Nếu điều này xảy ra, thì hợp đồng sẽ bị khóa vĩnh viễn và không thể thay đổi trạng thái của lockHolder. Nếu bạn sử dụng mutexes để phòng chống reentrancy, bạn sẽ cần chắc chắn rằng sẽ không có trường hợp bị khóa cứng như đoạn mã ở trên. (Có những nguy cơ tiềm tàng khác khi lập trình với mutexes, chẳng hạn như deadlocks và livelocks).\n\n## Front-Running (AKA Transaction-Ordering Dependence)\n\nỞ phần trên chúng ta đã đề cập đến thức khai thác và phòng chống kiểu tấn công reentrancy. Bây giờ chúng ta sẽ cùng tìm hiểu một kiểu tấn công khác trong Blockchain dựa vào đặc điểm rằng: thứ tự của các giao dịch (ví dụ: trong một block) có thể bị kiểm soát.\n\nMột giao dịch trước khi được xác minh được nằm trong mempool một thời gian ngắn, người ta có thể biết được những gì xảy ra với giao dịch trước khi nó được đưa vào một block. Điều này có thể gây rắc rối cho những sàn giao dịch phi tập trung, nơi mọi người có thể nhìn thấy tất cả các giao dịch. Để ngăn cản điều này thực sự rất khó. Ví dụ, tại các sàn giao dịch, sẽ tốt hơn nếu thực hiện đấu giá hàng loạt (điều này cũng bảo vệ chống lại việc phân tích giao dịch). Một cách khác là sử dụng sơ đồ pre-commit (Chúng tôi sẽ đi vào chi tiết ở phần sau).\n\n## Tràn số nguyên (underfow và overflow)\n\nChúng ta hãy còn xem đoạn mã dưới đây:\n\n```javascript\nmapping (address => uint256) public balanceOf;\n\n// INSECURE\nfunction transfer(address _to, uint256 _value) {\n    /* Check if sender has balance */\n    require(balanceOf[msg.sender] >= _value);\n    /* Add and subtract new balances */\n    balanceOf[msg.sender] -= _value;\n    balanceOf[_to] += _value;\n}\n\n// SECURE\nfunction transfer(address _to, uint256 _value) {\n    /* Check if sender has balance and for overflows */\n    require(balanceOf[msg.sender] >= _value && balanceOf[_to] + _value >= balanceOf[_to]);\n\n    /* Add and subtract new balances */\n    balanceOf[msg.sender] -= _value;\n    balanceOf[_to] += _value;\n}\n```\n\nNếu giá trị `balanceOf[_to]` đạt đến giá trị lớn nhất có thể (2 ^ 256 - 1), chúng ta tăng `balanceOf[_to]` lên, nó sẽ quay vòng về giá trị 0. Khi thực hiện phép tính với các biến, hãy xem xem việc giá trị uint có cơ hội tiếp cận một số lớn như vậy hay không. Hãy xem rằng các biến uint có thể thay đổi giá trị bởi những ai. Nếu bất kỳ người dùng nào có thể gọi các hàm cập nhật giá trị uint, thì rất là nguy hiểm. Sẽ an toàn hơn nếu chỉ có quản trị viên có quyền truy cập để thay đổi trạng thái của biến. Nếu người dùng chỉ có thể tăng thêm 1 lần một, có lẽ bạn cũng an toàn vì khó có cách nào khả thi để đạt đến giới hạn số.\n\nTương tự với underflow. Nếu một uint bị giảm giá trị đến một số âm nhỏ hơn 0, nó sẽ quay vòng lại số lớn nhất của kiểu dữ liệu.\n\nMột giải pháp đơn giản để giảm thiểu lỗi tràn số là sử dụng thư viện [SafeMath.sol](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/SafeMath.sol) cho các hàm số học.\n\n### Tìm hiểu chi tiết hơn về underflow\n\nBài dự thi của Doug Hoyte trong Solidity contest năm 2017 đã đề cập đến một vấn đề quan trọng. Đây là một phiên bản đơn giản hóa bài dự thi của Doug Hoyte:\n\n```javascript\ncontract UnderflowManipulation {\n    address public owner;\n    uint256 public manipulateMe = 10;\n    function UnderflowManipulation() {\n        owner = msg.sender;\n    }\n\n    uint[] public bonusCodes;\n\n    function pushBonusCode(uint code) {\n        bonusCodes.push(code);\n    }\n\n    function popBonusCode()  {\n        require(bonusCodes.length >=0);  // this is a tautology\n        bonusCodes.length--; // an underflow can be caused here\n    }\n\n    function modifyBonusCode(uint index, uint update)  {\n        require(index < bonusCodes.length);\n        bonusCodes[index] = update; // write to any index less than bonusCodes.length\n    }\n\n}\n```\n\nNhìn vào đoạn mã trên, thật khó để có thể gây tràn số dưới với biến `manipulateMe`. Tuy nhiên, với các mảng động được lưu trữ tuần tự, nên nếu một kẻ xấu muốn thay đổi thao tác, tất cả những gì họ cần làm là:\n\n- Gọi `popBonusCode` để underflow (Lưu ý: phương thức `Array.pop()` đã được thêm vào trong phiên bản Solidity 0.5.0)\n- Tính toán vị trí lưu trữ của biến  `manipulateMe`\n- Sửa đổi và cập nhật giá trị của mảng bằng cách sử dụng `notifyBonusCode`\n\n### Tấn công từ chối dịch vụ với revert\n\nChúng ta cùng xem một hợp đồng đấu giá đơn giản dưới đây\n\n```javascript\n// INSECURE\ncontract Auction {\n    address currentLeader;\n    uint highestBid;\n\n    function bid() payable {\n        require(msg.value > highestBid);\n\n        require(currentLeader.send(highestBid)); // Refund the old leader, if it fails then revert\n\n        currentLeader = msg.sender;\n        highestBid = msg.value;\n    }\n}\n```\n\nNếu kẻ tấn công sử dụng một hợp đồng thông minh với hàm fallback có chức năng revert mọi giao dịch đến, kẻ tấn công có thể giành chiến thắng trong bất kỳ cuộc đấu giá nào. Có nghĩa là hacker sẽ gửi số tiền cao hơn số tiền hiện tại vào hàm `bid()` và trở thành leader, sau đó hắn đảm bảo rằng khi ai đó gửi số tiền lớn hơn, thì khi xảy ra giao dịch hoàn lại tiền cho hacker, nó đều sẽ không thành công.. Bằng cách này, chúng có thể ngăn bất kỳ ai khác gọi hàm `bid()` và chúng sẽ là leader mãi mãi. Lời khuyên ở đây là chúng ta sẽ chia thành 2 hàm gửi tiền và rút tiền, người dùng khi không là leader nữa thì sẽ gọi hàm rút tiền để thu lại số tiền đã gửi vào hàm gửi tiền.\n\nMột ví dụ khác là khi  hợp đồng sử dụng vòng lặp để duyệt qua mảng nhằm trả tiền cho các người dùng (ví dụ: những người ủng hộ trong hợp đồng gây quỹ cộng đồng). Điều thông thường là muốn đảm bảo rằng mỗi khoản thanh toán thành công. Nếu không, giao dịch sẽ bị revert. Vấn đề là nếu giao dịch thất bại, bạn đang revert toàn bộ hệ thống thanh toán, nghĩa là vòng lặp sẽ không bao giờ được hoàn thành. Không ai được trả tiền vì một địa chỉ giao dịch bị lỗi.\n\n```javascript\naddress[] private refundAddresses;\nmapping (address => uint) public refunds;\n\n// bad\nfunction refundAll() public {\n    for(uint x; x < refundAddresses.length; x++) { // arbitrary length iteration based on how many addresses participated\n        require(refundAddresses[x].send(refunds[refundAddresses[x]])) // doubly bad, now a single failure on send will hold up all funds\n    }\n}\n```\n\n### Tấn công từ chối dịch vụ dựa với GasLimit\n\nMỗi block có giới hạn trên về lượng gas có thể được sử dụng, và do đó suy ra khối lượng tính toán có thể được thực hiện. Nếu lượng gas chi vượt quá giới hạn này, giao dịch sẽ thất bại. Điều này dẫn đến một vài nguy cơ có thể bị hacker tấn công từ chối dịch vụ.\n\n### Gas Limit DoS on a Contract via Unbounded Operations\n\nMột vấn đề khác với ví dụ trước: bằng cách thanh toán cho mọi người cùng một lúc, bạn có nguy cơ sử dụng quá lượng gas giới hạn.\n\nĐiều này có thể dẫn đến các vấn đề ngay cả khi không có một cuộc tấn công có chủ đích. Tuy nhiên, thật tệ nếu kẻ tấn công có thể thao túng lượng gas cần thiết. Trong trường hợp của ví dụ trước, kẻ tấn công có thể tạo một loạt địa chỉ, mỗi địa chỉ cần được hoàn lại một số tiền rất nhỏ. Do đó, chi phí gas cho việc hoàn trả tiền cho từng địa chỉ của kẻ tấn công có thể vượt lượng gas, ngăn chặn giao dịch hoàn tiền có thể xảy ra cho những người dùng khác.\n\nNếu bạn phải sử dụng vòng lặp để duyệt qua một mảng có kích thước không xác định, bạn nên để chúng diễn ra dàn trải trên nhiều block. Như trong ví dụ sau:\n\n```javascript\nstruct Payee {\n    address addr;\n    uint256 value;\n}\n\nPayee[] payees;\nuint256 nextPayeeIndex;\n\nfunction payOut() {\n    uint256 i = nextPayeeIndex;\n    while (i < payees.length && msg.gas > 200000) {\n      payees[i].addr.send(payees[i].value);\n      i++;\n    }\n    nextPayeeIndex = i;\n}\n```\n\nBạn sẽ cần đảm bảo rằng sẽ không có gì xấu xảy ra nếu các giao dịch khác được xử lý trong khi chờ lần lặp tiếp theo của hàm `payOut()`. Vì vậy, chỉ sử dụng mô hình này nếu thực sự cần thiết.\n\n### Gas Limit DoS on the Network via Block Stuffing\n\nNgay cả khi hợp đồng của bạn không chứa vòng lặp, kẻ tấn công có thể ngăn các giao dịch khác được đưa vào blockchain trong một vài block bằng cách đặt một số giao dịch với lượng gas cao.\n\nĐể làm được điều này, kẻ tấn công sẽ phát hành một số giao dịch sẽ với lượng tổng lượng gas tiêu thụ tương đương với gasLimit, với phí gas đủ cao thì những giao dịch đấy sẽ được đưa vào block mới nhất. Không có gì đảm bảo một giao dịch có phí gas cao sẽ được đưa vào block, nhưng giá càng cao, cơ hội càng cao.\n\nNếu cuộc tấn công thành công, sẽ không có giao dịch nào khác được đưa vào block. Đôi khi, mục tiêu của kẻ tấn công là ngăn chặn các giao dịch gọi đến một hợp đồng cụ thể trong một khoảng thời gian.\n\nCuộc tấn công này đã xảy ra trên [Fomo3D](https://solmaz.io/2018/10/18/anatomy-block-stuffing/), một ứng dụng đánh bạc. Trò chơi sẽ có một bộ đếm ngược thời gia, khi bộ đếm ngược chạy về 0, ai là người mua \"chìa khóa\" cuối cùng sẽ là người lãnh thưởng. Kẻ tấn công đã mua một khóa và sau đó chúng đã nhồi các giao dịch có phí gas cao trong 13 block liên tiếp cho đến khi bộ đếm thời gian hết giờ và khoản tiền thưởng được giải phóng. Các giao dịch được gửi bởi kẻ tấn công đã tốn mất 7,9 triệu gas trên mỗi block, do đó lượng gas còn lại chỉ cho phép một vài giao dịch nhỏ (mất 21.000 gas mỗi lần), nhưng không cho phép bất kỳ giao dịch nào gọi đến hàm buyKey() (tốn 300.000+ gas).\n\nMột cuộc tấn công Block Stuffing có thể được sử dụng trên bất kỳ hợp đồng nào yêu cầu một hành động trong một khoảng thời gian nhất định. Tuy nhiên, như với bất kỳ cuộc tấn công nào, nó chỉ có lợi khi phần thưởng đạt được lớn hơn chi phí mà những kẻ tấn công phải bỏ ra. Chi phí của cuộc tấn công này tỷ lệ thuận với số block cần tấn công. Nếu hợp đồng của bạn gồm một khoản thanh toán lớn có thể có được bằng cách ngăn chặn các hành động từ những người dùng khác, thì nó có thể sẽ là mục tiêu của một cuộc tấn công như vậy.\n\n## Insufficient gas griefing\n\nPhương thức tấn công này có thể xảy ra đối với một hợp đồng chấp nhận sử dụng dữ liệu chung và nó thực hiện lời gọi một hợp trung gian (sub call) thông qua phương thức ở mức thấp `address.call()` .\n\nNếu một lời gọi thất bại, hợp đồng có 2 lựa chọn\n\n- Revert toàn bộ giao dịch\n- Tiếp tục thực thi\n\nVí dụ sau đây về lời gọi của hợp đồng Relayer sẽ tiếp tục thực thi bất kể kết quả của subcall:\n\n```javascript\ncontract Relayer {\n    mapping (bytes => bool) executed;\n\n    function relay(bytes _data) public {\n        // replay protection; do not call the same transaction twice\n        require(executed[_data] == 0, \"Duplicate call\");\n        executed[_data] = true;\n        innerContract.call(bytes4(keccak256(\"execute(bytes)\")), _data);\n    }\n}\n```\n\nHợp đồng này cho phép chuyển tiếp giao dịch. Ai đó muốn thực hiện giao dịch nhưng không thể tự thực hiện giao dịch (ví dụ do thiếu ether để thanh toán tiền gas) có thể ký dữ liệu mà anh ta muốn chuyển và chuyển dữ liệu bằng chữ ký của mình. Sau đó, một \"người chuyển tiếp\" bên thứ ba có thể gửi giao dịch này tới mạng thay mặt cho người dùng.\n\nNếu chỉ được cung cấp đủ lượng gas, Relayer sẽ hoàn thành việc ghi tham số `_data` vào trong mapping \\`\\`excuted\\`\\`\\`, nhưng subcall sẽ thất bại vì không nhận đủ gas để thực hiện xong.\n\nKẻ tấn công có thể sử dụng điều này để kiểm duyệt các giao dịch, khiến chúng thất bại bằng cách gửi chúng đi với một lượng gas thấp. Cuộc tấn công này không trực tiếp mang lại lợi ích cho kẻ tấn công, nhưng gây ra thiệt hại cho nạn nhân. Kẻ tấn công, sẵn sàng tiêu tốn một lượng khí nhỏ về mặt lý thuyết có thể kiểm duyệt tất cả các giao dịch theo cách này, nếu chúng là người đầu tiên gửi chúng cho Relayer.\n\nMột cách để giải quyết vấn đề này là triển khai logic mã nguồn yêu cầu các hợp đồng cung cấp đủ gas để hoàn thành subcall. Nếu một thợ đào đã cố gắng tiến hành cuộc tấn công theo kịch bản này, câu lệnh `require` sẽ thất bại và giao dịch sẽ bị revert. Người dùng có thể chỉ định gasLimit tối thiểu cùng với dữ liệu khác (trong ví dụ này, thông thường, giá trị \\_gasLimit sẽ được xác minh bằng chữ ký, nhưng điều đó được khuyến nghị vì đơn giản trong trường hợp này).\n\n```javascript\n// contract called by Relayer\ncontract Executor {\n    function execute(bytes _data, uint _gasLimit) {\n        require(gasleft() >= _gasLimit);\n        ...\n    }\n}\n```\n\nMột giải pháp khác là chỉ cho phép các tài khoản đáng tin cậy chuyển tiếp giao dịch.\n\n## Bắt buộc một hợp đồng phải nhận ether\n\nCó thể gửi Ether vào một hợp đồng mà không cần kích hoạt fallback function của hợp đồng đó. Đây là một cân nhắc quan trọng khi viết mã cho fallback function hoặc thực hiện các tính toán dựa trên số dư của hợp đồng. Lấy ví dụ sau:\n\n```javascript\ncontract Vulnerable {\n    function () payable {\n        revert();\n    }\n\n    function somethingBad() {\n        require(this.balance > 0);\n        // Do something bad\n    }\n}\n```\n\nLogic hợp đồng dường như không cho phép gửi ether vào hợp đồng. Tuy nhiên, một vài phương thức tồn tại để buộc hợp đồng nhận ether và làm cho số dư của nó lớn hơn 0.\n\nPhương thức `sefldestruct`  cho phép chỉ định tài khoản nhận ether và không có cách gì để ngăn cản điều đó. `sefldestruct` không kích hoạt fallback function của hợp đồng.\n\n## Các vụ hack lịch sử\n\nĐây là những cuộc tấn công không còn có thể thực hiện do những thay đổi trong giao thức hoặc do các bản cập nhật solidity.\n\n### Các lỗ hổng khác\n\n[Smart Contract Weakness Classification Registry](https://smartcontractsecurity.github.io/SWC-registry/) cơ cung cấp một danh mục đầy đủ cập nhật về các lỗ hổng hợp đồng thông minh đã biết và các cách chống lại chúng với các ví dụ trong thế giới thực. Hãy thường xuyên xem qua là một cách tốt để cập nhật các cuộc tấn công mới nhất.\n\n<a name=\"eng-techniques\"></a>\n\n# Áp dụng các nguyên tắc trong phát triển phần mềm để viết hợp đồng thông minh\n\nViệc bảo vệ trước các cuộc tấn công đã biết là không đủ. Vì chi phí thiệt hại trên blockchain có thể rất cao, bạn cũng phải điều chỉnh cách bạn viết phần mềm, để phòng tránh những rủi ro đó.\n\nCách tiếp cận chúng tôi  là \"chuẩn bị cho thất bại\". Không thể biết trước được liệu mã nguồn của bạn có an toàn hay không ? Tuy nhiên, bạn có thể thiết kế các hợp đồng của mình theo cách cho phép chúng thất bại với thiệt hại tối thiểu. Phần này trình bày một loạt các kỹ thuật sẽ giúp bạn chuẩn bị cho thất bại.\n\n*Lưu ý*: Luôn có rủi ro khi bạn thêm một thành phần mới vào hệ thống của mình. Hãy suy nghĩ kỹ về từng kỹ thuật bạn sử dụng trong các hợp đồng của mình và xem xét cẩn thận cách chúng phối hợp với nhau để tạo ra một hệ thống an toàn.\n\n## Nâng cấp hợp đồng bị lỗi\n\nMã nguồn sẽ cần phải được thay đổi nếu phát hiện lỗi hoặc vì lý do cần cải thiện.\n\nThiết kế một hệ thống nâng cấp hiệu quả cho các hợp đồng thông minh là một lĩnh vực nghiên cứu và chúng tôi sẽ không thể đề cập đến tất cả các vấn đề trong tài liệu này được. Tuy nhiên, có hai cách tiếp cận cơ bản được sử dụng phổ biến nhất. Cách thứ nhất là tạo một hợp đồng giữ địa chỉ phiên bản mới nhất của các hợp đồng khác. Một cách tiếp cận khác là có một hợp đồng chuyển tiếp các lời gọi và dữ liệu đến phiên bản mới nhất của hợp đồng.\n\nDù là kỹ thuật nào, điều quan trọng là mã nguồn được mô đun hóa và phân tách tốt giữa các thành phần, để nếu một thay đổi xảy ra sẽ không phá vỡ cấu trúc của toàn bộ hệ thống.\n\nĐiều quan trọng là có một cách an toàn để các bên quyết định nâng cấp mã. Tùy thuộc vào hợp đồng của bạn, các thay đổi mã nguồn có thể cần được chấp thuận bởi một bên đáng tin cậy, một nhóm thành viên hoặc bỏ phiếu của toàn bộ các bên liên quan. Nếu quá trình này có thể mất một chút thời gian, bạn sẽ muốn xem xét liệu có cách nào khác để phản ứng nhanh hơn trong trường hợp bị tấn công, chẳng hạn như dừng khẩn cấp hoặc ngắt mạch.\n\n### Ví dụ 1: Sử dụng hợp đồng để lưu trữ địa chỉ phiên bản mới nhất của các hợp đồng khác\n\n```javascript\ncontract SomeRegister {\n    address backendContract;\n    address[] previousBackends;\n    address owner;\n\n    function SomeRegister() {\n        owner = msg.sender;\n    }\n\n    modifier onlyOwner() {\n        require(msg.sender == owner)\n        _;\n    }\n\n    function changeBackend(address newBackend) public\n    onlyOwner()\n    returns (bool)\n    {\n        if(newBackend != backendContract) {\n            previousBackends.push(backendContract);\n            backendContract = newBackend;\n            return true;\n        }\n\n        return false;\n    }\n}\n```\n\nCó hai nhược điểm chính trong cách tiếp cận này:\n\n1. Người dùng phải luôn luôn kiểm tra địa chỉ mới nhất của hợp đồng cần gọi đến và bất kỳ ai không thực hiện điều này có thể gặp rủi ro khi tương tác với các phiên bản cũ của hợp đồng.\n1. Bạn sẽ cần suy nghĩ cẩn thận về cách xử lý dữ liệu hợp đồng khi bạn thay thế hợp đồng mới.\n\n### Ví dụ 2: Sử dụng \\`\\`\\`delegatecall\\`\\` cho việc chuyển tiếp lời gọi và dữ liệu đến hợp đồng.\n\n```javascript\ncontract Relay {\n    address public currentVersion;\n    address public owner;\n\n    modifier onlyOwner() {\n        require(msg.sender == owner);\n        _;\n    }\n\n    function Relay(address initAddr) {\n        currentVersion = initAddr;\n        owner = msg.sender; // this owner may be another contract with multisig, not a single contract owner\n    }\n\n    function changeContract(address newVersion) public\n    onlyOwner()\n    {\n        currentVersion = newVersion;\n    }\n\n    function() {\n        require(currentVersion.delegatecall(msg.data));\n    }\n}\n```\n\nCách tiếp cận này tránh được các vấn đề ở ví dụ 1 ở trên nhưng cũng có vấn đề của riêng nó. Bạn phải cực kỳ cẩn thận với cách bạn lưu trữ dữ liệu trong hợp đồng này. Nếu hợp đồng mới của bạn có bố cục lưu trữ khác với hợp đồng đầu tiên, dữ liệu của bạn có thể bị hỏng. Ngoài ra, phiên bản đơn giản này của không thể trả về giá trị từ các hàm, chỉ chuyển tiếp chúng, làm hạn chế khả năng ứng dụng của nó.\n\n## Bộ ngắt  (Tạm dừng chức năng của hợp đồng)\n\nBộ ngắt sẽ dừng việc thực thi nếu thỏa mãn một số điều kiện nhất định và nó có thể hữu ích khi phát hiện ra lỗi mới. Ví dụ: hầu hết các hành động có thể bị đình chỉ trong hợp đồng nếu phát hiện ra lỗi và hành động duy nhất hiện đang hoạt động là rút tiền. Bạn có thể cung cấp cho các bên đáng tin cậy khả năng kích hoạt bộ ngắt hoặc có thể lập trình để tự động hóa kích hoạt bộ ngắt khi gặp một số trường hợp nhất định.\n\n```javascript\nbool private stopped = false;\naddress private owner;\n\nmodifier isAdmin() {\n    require(msg.sender == owner);\n    _;\n}\n\nfunction toggleContractActive() isAdmin public {\n    // You can add an additional modifier that restricts stopping a contract to be based on another action, such as a vote of users\n    stopped = !stopped;\n}\n\nmodifier stopInEmergency { if (!stopped) _; }\nmodifier onlyInEmergency { if (stopped) _; }\n\nfunction deposit() stopInEmergency public {\n    // some code\n}\n\nfunction withdraw() onlyInEmergency public {\n    // some code\n}\n```\n\n## Trì hoãn hành động của hợp đồng\n\nVới việc trì hoãn các hành đồng từ hợp đồng, chúng ta sẽ có thêm thời gian để phục hồi hệ thống nếu bị tấn công. Ví dụ, đoạn mã ở dưới chỉ cho phép người dùng rút tiền sau 28 ngày kể từ lúc yêu câu rút tiền được gửi đến hợp đồng.\n\n```javascript\nstruct RequestedWithdrawal {\n    uint amount;\n    uint time;\n}\n\nmapping (address => uint) private balances;\nmapping (address => RequestedWithdrawal) private requestedWithdrawals;\nuint constant withdrawalWaitPeriod = 28 days; // 4 weeks\n\nfunction requestWithdrawal() public {\n    if (balances[msg.sender] > 0) {\n        uint amountToWithdraw = balances[msg.sender];\n        balances[msg.sender] = 0; // for simplicity, we withdraw everything;\n        // presumably, the deposit function prevents new deposits when withdrawals are in progress\n\n        requestedWithdrawals[msg.sender] = RequestedWithdrawal({\n            amount: amountToWithdraw,\n            time: now\n        });\n    }\n}\n\nfunction withdraw() public {\n    if(requestedWithdrawals[msg.sender].amount > 0 && now > requestedWithdrawals[msg.sender].time + withdrawalWaitPeriod) {\n        uint amountToWithdraw = requestedWithdrawals[msg.sender].amount;\n        requestedWithdrawals[msg.sender].amount = 0;\n\n        require(msg.sender.send(amountToWithdraw));\n    }\n}\n```\n\n## Giới hạn tỷ lệ\n\nVí dụ: người gửi tiền chỉ có thể được phép rút một số tiền hoặc tỷ lệ phần trăm của tổng số tiền gửi trong một khoảng thời gian nhất định (ví dụ: tối đa 100 ether trong 1 ngày) - rút tiền bổ sung trong khoảng thời gian đó có thể thất bại hoặc hợp đồng sẽ yêu cầu một số phê duyệt đặc biệt. Hoặc ta giới hạn tỷ lệ có thể ở hợp đồng, chỉ với một số lượng mã token nhất định do hợp đồng phát hành trong một khoảng thời gian.\n\n```javascript\ncontract CircuitBreaker {\n  struct Transfer { \n      uint amount; \n      address to; \n      uint releaseBlock;\n      bool released; \n      bool stopped; \n  }\n  \n  Transfer[] public transfers;\n\n  address public curator;\n  address public authorizedSender;\n  uint public period;\n  uint public limit;\n\n  uint public currentPeriodEnd;\n  uint public currentPeriodAmount;\n\n  event PendingTransfer(uint id, uint amount, address to, uint releaseBlock);\n\n  function CircuitBreaker(address _curator, address _authorizedSender, uint _period, uint _limit) {\n    curator = _curator;\n    period = _period;\n    limit = _limit;\n    authorizedSender = _authorizedSender;\n    currentPeriodEnd = block.number + period;\n  }\n\n  function transfer(uint amount, address to) {\n    if (msg.sender == authorizedSender) {\n      updatePeriod();\n\n      if (currentPeriodAmount + amount > limit) {\n        uint releaseBlock = block.number + period;\n        PendingTransfer(transfers.length, amount, to, releaseBlock);\n        transfers.push(Transfer(amount, to, releaseBlock, false, false));\n      } else {\n        currentPeriodAmount += amount;\n        transfers.push(Transfer(amount, to, block.number, true, false));\n        if(!to.send(amount)) throw;\n      }\n    }\n  } \n  \n  function updatePeriod() {\n    if (currentPeriodEnd < block.number) {\n      currentPeriodEnd = block.number + period;\n      currentPeriodAmount = 0;\n    }\n  }\n\n  function releasePendingTransfer(uint id) {\n    Transfer transfer = transfers[id];\n    if (transfer.releaseBlock <= block.number && !transfer.released && !transfer.stopped) {\n      transfer.released = true;\n      if(!transfer.to.send(transfer.amount)) throw;\n    }\n  }\n  \n  function stopTransfer(uint id) {\n    if (msg.sender == curator) {\n      transfers[id].stopped = true;\n    }\n  }\n}\n```\n\n## Triển khai hợp đồng\n\nHợp đồng nên có thời gian thử nghiệm - trước khi triển khai chính thức.\n\nTối thiểu, bạn nên:\n\n- Kiểm thử đầy đủ với test coverage 100% (hoặc gần bằng)\n- Deploy lên mạng thử nghiệm local (local testnet)\n- Triển khai trên testnet public\n- Triển khai trên mainnet ở phiên bản beta\n\n#### AUTOMATIC DEPRECATION\n\nTrong quá trình thử nghiệm, bạn có thể ngăn chặn mọi hành động, sau một khoảng thời gian nhất định. Ví dụ: hợp đồng alpha có thể hoạt động trong vài tuần và sau đó tự động tắt tất cả các hành động, ngoại trừ lần rút tiền cuối cùng.\n\n```javascript\nmodifier isActive() {\n    require(block.number <= SOME_BLOCK_NUMBER);\n    _;\n}\n\nfunction deposit() public isActive {\n    // some code\n}\n\nfunction withdraw() public {\n    // some code\n}\n```\n\n#### GIỚI HẠN SỐ TIỀN CỦA MỌI NGƯỜI DÙNG / HỢP ĐỒNG\n\nTrong giai đoạn đầu, bạn có thể hạn chế lượng Ether cho bất kỳ người dùng nào (hoặc cho toàn bộ hợp đồng) - để thiểu giảm rủi ro.\n\n### Trả thưởng cho những người tìm ra lỗi (Bug Bounty Program)\n\nCác tips cho việc áp dụng việc trả thưởng cho người tìm ra lỗi:\n\n- Quyết định xem loại tiền nào sẽ được dùng để trả thưởng (ETH hay BTC ...)\n- Quyết định xem tổng ngân sách trả thưởng là bao nhiêu\n- Từ ngân sách, xác định ba loại phần thưởng:\n  - phần thưởng nhỏ nhất bạn sẵn sàng đưa ra\n  - phần thưởng cao nhất được trao là bao nhiêu\n  - một số điều khoản bổ sung nếu trong trường hợp lỗ hổng rất nghiêm trọng\n- Xác định các chuyên gia để đánh giá mức độ nghiêm trọng của lỗ hổng\n- Lead developer có thể là một trong các chuyên gia để đánh giá mức độ nghiêm trọng của lỗ hổng\n- Khi nhận được báo cáo lỗ hổng, các chuyên gia sẽ đánh giá xem lỗ hổng có mức độ nghiêm trọng như thế nào\n- Hỏi xem người săn lỗi có bản vá hay chưa ? Nếu chưa có thì đội phát triển cần đưa ra bản vá một cách nhanh chóng\n- Trả thưởng cho người tìm ra lỗi\n\nCác bạn có thể tham khảo chương trình của Ethereum [Ethereum's Bounty Program](https://bounty.ethereum.org/)\n\n<a name=\"token\"></a>\n\n# Lời khuyên cho việc implement mã Token\n\n## Tuân thủ tiêu chuẩn mới nhất\n\nNói chung, hợp đồng thông minh của mã token phải tuân theo tiêu chuẩn  đax được cộng đồng chấp nhận và xem là ổn định. Ví dụ về các tiêu chuẩn hiện được chấp nhận là:\n\n- [EIP20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md)\n- [EIP721](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md)\n\n## Lưu ý về các cuộc tấn công với EIP-20\n\nHàm `approve()` của token EIP-20 có thể dẫn đến trường hợp người dùng có số tiền chi tiêu được phê duyệt chi tiêu nhiều hơn số tiền dự định. Một cuộc tấn công front-running có thể được sử dụng, cho phép một kẻ xấu gọi `transferFrom()` cả trước và sau khi gọi `approve()` được xử lý. Thông tin chi tiết có sẵn trên [EIP](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#approve) và trong [tài liệu này](https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/edit).\n\n## Tránh việc chuyển token đến địa chỉ 0x0\n\nTại thời điểm viết, địa chỉ \"không\" [0x0000000000000000000000000000000000000000](https://etherscan.io/address/0x0000000000000000000000000000000000000000) giữ các mã token có giá trị hơn 80 triệu đô la !\n\n## Tránh việc chuyển token đến chính hợp đồng của gửi token\n\nXem xét cũng ngăn chặn việc chuyển token đến chính địa chỉ của hợp đồng thông minh gửi token.\n\nMột ví dụ về trường hợp này là hợp đồng thông minh [EOS](https://etherscan.io/address/0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0) nơi có hơn 90.000 token bị kẹt tại địa chỉ hợp đồng.\n\n## Ví dụ\n\nMột ví dụ về việc thực hiện cả hai khuyến nghị trên sẽ viết một modifier; xác thực rằng địa chỉ \"đến\" không phải là 0x0 cũng không phải là địa chỉ của hợp đồng thông minh:\n\n```javascript\n modifier validDestination( address to ) {\n        require(to != address(0x0));\n        require(to != address(this) );\n        _;\n    }\n```\n\nModifier  được áp dụng cho các phương thức \"transfer\" và \"transferFrom\":\n\n```javascript\n function transfer(address _to, uint _value)\n        validDestination(_to)\n        returns (bool) \n    {\n        (... your logic ...)\n    }\n\n    function transferFrom(address _from, address _to, uint _value)\n        validDestination(_to)\n        returns (bool) \n    {\n        (... your logic ...)\n    }\n```\n\n<a name=\"document\"></a>\n\n# Tài liệu và thủ tục\n\nKhi triển khai một hợp đồng, điều quan trọng là phải bao gồm tài liệu thích hợp cho các biên liên quan có thể tìm hiểu. Một số tài liệu liên quan đến bảo mật bao gồm:\n\n## Thông số kỹ thuật và kế hoạch triển khai\n\n- Thông số kỹ thuật, sơ đồ, trạng thái, mô hình và tài liệu khác giúp người đánh giá và cộng đồng hiểu hệ thống dự định làm gì.\n- Nhiều lỗi có thể được tìm thấy chỉ từ các thông số kỹ thuật, và chúng không tốn kém lắm để có thể sửa chữa.\n\n## Trạng thái\n\n- Nơi mã nguồn hiện tại được triển khai\n- Phiên bản trình biên dịch, các bước để xác minh bytecode được triển khai khớp với mã nguồn\n- Các phiên bản trình biên dịch sẽ được sử dụng cho các giai đoạn khác nhau.\n- Trạng thái hiện tại của mã nguồn được triển khai (bao gồm các sự cố còn tồn tại, số liệu thống kê hiệu suất, v.v.)\n\n## Nắm bắt được các vấn đề\n\n- Ước lượng rủi ro chính với hợp đồng\n- ví dụ: Bạn có thể mất tất cả tiền của mình, hacker có thể thực hiện một số hành đồng trái phép\n- Nắm được tất cả các lỗi/giới hạn\n- Các cuộc tấn công và giảm nhẹ thiệt hại\n\n## Lịch sử\n\n- Kiểm thử (bao gồm thống kê sử dụng, phát hiện lỗi, thời gian thử nghiệm)\n- Những người đã review mã nguồn (và phản hồi chính của họ)\n\n## Thủ tục\n\n- Kế hoạch hành động trong trường hợp phát hiện ra lỗi (ví dụ: tùy chọn khẩn cấp, quy trình thông báo công khai, v.v.)\n- Kết thúc quá trình nếu có sự cố xảy ra (ví dụ: các nhà tài trợ sẽ nhận được phần trăm số dư của bạn trước khi tấn công, từ số tiền còn lại)\n- Chính sách công bố có trách nhiệm (ví dụ: nơi báo cáo lỗi được tìm thấy, các quy tắc của bất kỳ chương trình tiền thưởng lỗi nào)\n- Phòng ngừa trong trường hợp thất bại (ví dụ: bảo hiểm, ...)\n\n## Thông tin liên lạc\n\n- Ai liên hệ được liên hệ khi xảy ra các vấn đề\n- Phòng chat nơi câu hỏi có thể được hỏi\n\n<a name=\"tools\"></a>\n\n# Các công cụ bảo mật\n\n## Công cụ trực quan hóa\n\n- [Sūrya](https://github.com/ConsenSys/surya)  - Công cụ tiện ích cho các hệ thống hợp đồng thông minh, cung cấp một số kết quả đầu ra trực quan và thông tin về cấu trúc của hợp đồng. Nó hỗ trợ tính năng biểu đồ cho các lời gọi hàm.\n- [Solgraph](https://github.com/raineorshine/solgraph)  - Tạo biểu đồ DOT trực quan hóa luồng điều khiển chức năng của hợp đồng Solidity và làm nổi bật các lỗ hổng bảo mật tiềm ẩn.\n- [EVM Lab](https://github.com/ethereum/evmlab)  - Gói công cụ phong phú để tương tác với EVM. Bao gồm VM, API Etherchain.\n- [ethereum-graph-debugger](https://github.com/fergarrui/ethereum-graph-debugger)  - Một trình gỡ lỗi EVM bằng đồ họa. Hiển thị toàn bộ biểu đồ luồng điều khiển chương trình.\n\n## Static and Dynamic Analysis\n\n- [MythX](https://mythx.io/)  - Các công cụ và extension phân tích bảo mật chuyên nghiệp cho Truffle, Embark và các môi trường khác.\n- [Mythril](https://github.com/ConsenSys/mythril)  - Một con dao quân đội Thụy Sĩ thực thụ cho bảo mật hợp đồng thông minh.\n- [Slither](https://github.com/trailofbits/slither)  - Framework phân tích cho nhiều vấn đề phổ biến với Solidity. Nó viết bằng Python.\n- [Echidna](https://github.com/trailofbits/echidna)  - Trong môi trường testing,  tạo đầu vào độc hại nhằm phá vỡ hợp đồng thông minh.\n- [Manticore](https://github.com/trailofbits/manticore)  - Công cụ phân tích mã nhị phân với sự hỗ trợ EVM.\n- [Oyente](https://github.com/melonproject/oyente)  - Phân tích mã Ethereum để tìm các lỗ hổng phổ biến.\n- [Securify](https://github.com/eth-sri/securify2)  -phân tích trực tuyến một cách hoàn toàn tự động cho các hợp đồng thông minh, cung cấp các báo cáo bảo mật dựa trên các lỗ hổng đã biết.\n- [SmartCheck](https://tool.smartdec.net/)  - Phân tích tĩnh mã nguồn Solidity với các lỗ hổng bảo mật.\n- [Octopus](https://github.com/quoscient/octopus)  - Công cụ phân tích bảo mật cho hợp đồng thông minh Blockchain với sự hỗ trợ của EVM và (e) WASM.\n\n## Weakness OSSClassifcation & Test Cases\n\n- [SWC-registry](https://github.com/SmartContractSecurity/SWC-registry/)  - Các định nghĩa SWC và một repo lớn các mẫu hợp đồng thông minh dễ bị tấn công.\n- [SWC Pages](https://smartcontractsecurity.github.io/SWC-registry/)  - Repo đăng ký SWC được xuất bản trên Github Pages.\n\n## Test Coverage\n\n- [solidity-coverage](https://github.com/sc-forks/solidity-coverage)  - Code coverage và Solidity testing.\n\n## Linters\n\nLinters cải thiện chất lượng mã nguồn bằng cách thực thi các quy tắc làm cho mã dễ đọc và xem xét hơn.\n\n- [Solcheck](https://github.com/federicobond/solcheck)  - Một phiên bản eslint cho mã Solidity được viết bằng JS.\n- [Solint](https://github.com/weifund/solint)  - Solid linting giúp bạn thực thi các quy ước nhất quán và tránh các lỗi trong hợp đồng thông minh Solidity của bạn.\n- [Solium](https://github.com/duaraghav8/Solium)\n- [Solhint](https://github.com/protofire/solhint)  - Cung cấp cho người dùng viết Solidity một cách Bảo mật và Phong cách.\n\n<a name=\"eip\"></a>\n\n# EIPS\n\n## Các đề xuất EIP liên quan đến bảo mật\n\nCác đề xuất EIP sau đây rất quan trọng để nhận biết, hiểu cách EVM hoạt động hoặc thông báo các kỹ thuật mới áp dụng khi phát triển hệ thống hợp đồng thông minh.\n\nDưới đây chưa phải là một danh sách thật sự đầy đủ\n\n### Các đề xuất hoàn chỉnh\n\n- [EIP 155](https://eips.ethereum.org/EIPS/eip-155)  Bảo vệ trước các vụ tấn công replay đơn giản\n- [EIP 214](https://eips.ethereum.org/EIPS/eip-214)  Opcode STATICCALL mới - Thêm một opcode mới có thể được sử dụng để gọi một hợp đồng khác (hoặc chính nó) trong khi không cho phép bất kỳ sửa đổi nào đối với trạng thái trong suốt lời gọi.\n- [EIP 607](https://eips.ethereum.org/EIPS/eip-607) Triển khai các biện pháp phồng chống tấn công replay đơn giản từ EIP 155.\n- [EIP 779](https://eips.ethereum.org/EIPS/eip-779) Tài liệu này ghi lại những thay đổi có trong hard fork có tên là \"DAO Fork\". Không giống như các hard fork khác, DAO Fork không thay đổi giao thức; tất cả các mã EVM, định dạng giao dịch, cấu trúc block, v.v vẫn giữ nguyên.\n\n### Các đề xuất còn đang trong quá trình sửa đổi, phát triển\n\n- [EIP 1470](https://eips.ethereum.org/EIPS/eip-1470)  Phân loại điểm yếu hợp đồng thông minh - Đề xuất một sơ đồ phân loại cho các điểm yếu bảo mật trong hợp đồng thông minh Ethereum. (SWC)\n- [EIP 1051](https://eips.ethereum.org/EIPS/eip-1051) Kiểm tra lỗi Overflow cho EVM - Thêm hai opcode mới cho phép phát hiện và ngăn chặn overflow hiệu quả.\n- [EIP 1271](https://eips.ethereum.org/EIPS/eip-1271) Phương thức xác thực chữ ký tiêu chuẩn cho hợp đồng thông minh - Thiết kế hiện tại của nhiều hợp đồng thông minh là không có khóa riêng (private key) và do đó không thể ký trực tiếp message. Đề xuất ở đây phác thảo một cách tiêu chuẩn cho các hợp đồng để xác minh xem chữ ký được cung cấp có hợp lệ khi tài khoản là hợp đồng không ?\n\n<a name=\"resource\"></a>\n\n# Các tài nguyên tham khảo\n\nDưới đây là danh sách các nguồn tài nguyên hữu ích để tham khải về bảo mật trong Ethereum cũng như Solidity. Nguồn tin chính thống thông báo về các vấn đề bảo mật là Blog Ethereum, nhưng trong nhiều trường hợp, các lỗ hổng sẽ được tiết lộ và thảo luận trước đó ở các nơi khác.\n\n- [Ethereum Blog](https://blog.ethereum.org/): The official Ethereum blog\n- [Ethereum Gitter](https://gitter.im/orgs/ethereum/rooms)  chat rooms\n  - [Solidity](https://gitter.im/ethereum/solidity)\n  - [Go-Ethereum](https://gitter.im/ethereum/go-ethereum)\n  - [CPP-Ethereum](https://gitter.im/ethereum/cpp-ethereum)\n  - [Research](https://gitter.im/ethereum/research)\n- [Smart Contract Security Weekly](https://tinyletter.com/smart-contract-security):Cập nhật hàng tuần về thông Hợp đồng thông minh Ethereum và Bảo mật cơ sở hạ tầng ([Past Articles](https://tinyletter.com/smart-contract-security/archive))\n- [Reddit](https://www.reddit.com/r/ethereum)\n- [Network Stats](https://ethstats.net/)\n\nChúng tôi khuyên bạn nên thường xuyên đọc các nguồn này, vì các phương pháp khai thác phát hiện có thể ảnh hưởng đến hợp đồng của bạn.\n\nNgoài ra, đây là danh sách các nhà phát triển của Ethereum:\n\n- **Vitalik Buterin**:  [Twitter](https://twitter.com/vitalikbuterin),  [Github](https://github.com/vbuterin),  [Reddit](https://www.reddit.com/user/vbuterin),  [Ethereum Blog](https://blog.ethereum.org/author/vitalik-buterin/)\n- **Dr. Christian Reitwiessner**:  [Twitter](https://twitter.com/ethchris),  [Github](https://github.com/chriseth),  [Ethereum Blog](https://blog.ethereum.org/author/christian_r/)\n- **Dr. Gavin Wood**:  [Twitter](https://twitter.com/gavofyork),  [Blog](http://gavwood.com/),  [Github](https://github.com/gavofyork)\n- **Vlad Zamfir**:  [Twitter](https://twitter.com/vladzamfir),  [Github](https://github.com/vladzamfir),  [Ethereum Blog](https://blog.ethereum.org/author/vlad/)\n\nVà cuối cùng, chúng ta có the tham khảo các danh sách các bài viết về bảo mật trong Ethereum được viết từ các nhà phát triển Ethereum đến những người khác trong cộng động.\n\n#### Viết bởi các nhà phát triển Ethereum\n\n- [How to Write Safe Smart Contracts](https://chriseth.github.io/notes/talks/safe_solidity)  (Christian Reitwiessner)\n- [Smart Contract Security](https://blog.ethereum.org/2016/06/10/smart-contract-security/)  (Christian Reitwiessner)\n- [Thinking about Smart Contract Security](https://blog.ethereum.org/2016/06/19/thinking-smart-contract-security/)  (Vitalik Buterin)\n- [Solidity](http://solidity.readthedocs.io/)\n- [Solidity Security Considerations](http://solidity.readthedocs.io/en/latest/security-considerations.html)\n\n#### Viết bởi cộng đồng\n\n- [https://blog.sigmaprime.io/solidity-security.html](https://blog.sigmaprime.io/solidity-security.html)\n- [http://forum.ethereum.org/discussion/1317/reentrant-contracts](http://forum.ethereum.org/discussion/1317/reentrant-contracts)\n- [http://hackingdistributed.com/2016/06/16/scanning-live-ethereum-contracts-for-bugs/](http://hackingdistributed.com/2016/06/16/scanning-live-ethereum-contracts-for-bugs/)\n- [http://hackingdistributed.com/2016/06/18/analysis-of-the-dao-exploit/](http://hackingdistributed.com/2016/06/18/analysis-of-the-dao-exploit/)\n- [http://hackingdistributed.com/2016/06/22/smart-contract-escape-hatches/](http://hackingdistributed.com/2016/06/22/smart-contract-escape-hatches/)\n- [http://martin.swende.se/blog/Devcon1-and-contract-security.html](http://martin.swende.se/blog/Devcon1-and-contract-security.html)\n- [http://publications.lib.chalmers.se/records/fulltext/234939/234939.pdf](http://publications.lib.chalmers.se/records/fulltext/234939/234939.pdf)\n- [http://vessenes.com/deconstructing-thedao-attack-a-brief-code-tour](http://vessenes.com/deconstructing-thedao-attack-a-brief-code-tour)\n- [http://vessenes.com/ethereum-griefing-wallets-send-w-throw-considered-harmful](http://vessenes.com/ethereum-griefing-wallets-send-w-throw-considered-harmful)\n- [http://vessenes.com/more-ethereum-attacks-race-to-empty-is-the-real-deal](http://vessenes.com/more-ethereum-attacks-race-to-empty-is-the-real-deal)\n- [https://blog.blockstack.org/simple-contracts-are-better-contracts-what-we-can-learn-from-the-dao-6293214bad3a](https://blog.blockstack.org/simple-contracts-are-better-contracts-what-we-can-learn-from-the-dao-6293214bad3a)\n- [https://blog.slock.it/deja-vu-dao-smart-contracts-audit-results-d26bc088e32e](https://blog.slock.it/deja-vu-dao-smart-contracts-audit-results-d26bc088e32e)\n- [https://blog.vdice.io/wp-content/uploads/2016/11/vsliceaudit_v1.3.pdf](https://blog.vdice.io/wp-content/uploads/2016/11/vsliceaudit_v1.3.pdf)\n- [https://eprint.iacr.org/2016/1007.pdf](https://eprint.iacr.org/2016/1007.pdf)\n- [https://github.com/Bunjin/Rouleth/blob/master/Security.md](https://github.com/Bunjin/Rouleth/blob/master/Security.md)\n- [https://github.com/LeastAuthority/ethereum-analyses](https://github.com/LeastAuthority/ethereum-analyses)\n- [https://github.com/bokkypoobah/ParityMultisigRecoveryReconciliation](https://github.com/bokkypoobah/ParityMultisigRecoveryReconciliation)\n- [https://medium.com/@ConsenSys/assert-guards-towards-automated-code-bounties-safe-smart-contract-coding-on-ethereum-8e74364b795c](https://medium.com/@ConsenSys/assert-guards-towards-automated-code-bounties-safe-smart-contract-coding-on-ethereum-8e74364b795c)\n- [https://medium.com/@coriacetic/in-bits-we-trust-4e464b418f0b](https://medium.com/@coriacetic/in-bits-we-trust-4e464b418f0b)\n- [https://medium.com/@hrishiolickel/why-smart-contracts-fail-undiscovered-bugs-and-what-we-can-do-about-them-119aa2843007](https://medium.com/@hrishiolickel/why-smart-contracts-fail-undiscovered-bugs-and-what-we-can-do-about-them-119aa2843007)\n- [https://medium.com/@peterborah/we-need-fault-tolerant-smart-contracts-ec1b56596dbc](https://medium.com/@peterborah/we-need-fault-tolerant-smart-contracts-ec1b56596dbc)\n- [https://medium.com/zeppelin-blog/zeppelin-framework-proposal-and-development-roadmap-fdfa9a3a32ab](https://medium.com/zeppelin-blog/zeppelin-framework-proposal-and-development-roadmap-fdfa9a3a32ab)\n- [https://pdaian.com/blog/chasing-the-dao-attackers-wake](https://pdaian.com/blog/chasing-the-dao-attackers-wake)\n- [http://www.comp.nus.edu.sg/~loiluu/papers/oyente.pdf](http://www.comp.nus.edu.sg/~loiluu/papers/oyente.pdf)\n\n# Các chương trình thưởng cho những người tìm ra lỗi\n\nSau đây là các chương trình tiền thưởng cho lỗi đang diễn ra, tập trung vào việc tìm lỗi cuar các hợp đồng thông minh.\n\n- [0xProject](https://0xproject.com/wiki#Bug-Bounty)\n- [Airswap](https://medium.com/fluidity/smart-contracts-and-bug-bounty-ad75733eb53f)\n- [Augur](https://www.augur.net/bounty/)\n- [Aragon](https://wiki.aragon.org/dev/bug_bounty/)\n- [BrickBlock](https://blog.brickblock.io/join-the-brickblock-bug-bounty-program-7b431f2bcc02)\n- [Colony.io](https://blog.colony.io/announcing-the-colony-network-bug-bounty-f44cabaca9a3/)\n- [Ethereum Foundation](https://bounty.ethereum.org/#bounty-scope)\n- [Etherscan.io](https://etherscan.io/bugbounty)\n- [Gitcoin Bounties](https://gitcoin.co/explorer)\n- [MelonPort](https://melonport.com/bug-bounty)\n- [Parity](https://www.parity.io/bug-bounty/)\n- [Raiden.network](https://raiden.network/bug-bounty.html)\n\n## Reviewers\n\n## The following people have reviewed this document (date and commit they reviewed in parentheses): Bill Gleim (07/29/2016 3495fb5) Bill Gleim (03/15/2017 0244f4e)\n\n## License\n\nLicensed under [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0)\n\nLicensed under [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)\n"
  },
  {
    "path": "README-zh.md",
    "content": "# 以太坊智能合约 —— 最佳安全开发指南\n\n**Notice: this translation was generously provided by a contributor. The maintainers are not able to verify the content. Any issues or PRs to help improve it are welcome.**\n\n\\*本文翻译自：https://github.com/ConsenSys/smart-contract-best-practices\n\n为了使语句表达更加贴切，个别地方未按照原文逐字逐句翻译，如有出入请以原文为准。\\*\n\n**主要章节如下**:\n\n- [**Solidity安全贴士**](#solidity-tips)\n- [**已知的攻击手段**](#known-attacks)\n  - [***竞态***](#race-conditions)\n    - [***可重入***](#reentrancy)\n    - [***交易顺序依赖***](#transaction-ordering-dependence)\n  - [***针对Gas的攻击***](#dos-with-block-gas-limit)\n  - [***整数上溢/整数下溢***](#integer-overflow-and-underflow)\n- [**软件工程开发技巧**](#eng-techniques)\n- [**参考文献**](#bibliography)\n\n这篇文档旨在为Solidity开发人员提供一些智能合约的安全准则(**security baseline**)。当然也包括智能合约的**安全开发理念、bug赏金计划指南、文档例程以及工具。**\n\n我们邀请社区对该文档提出修改或增补建议，欢迎各种合并请求(Pull Request)。若有相关的文章或者博客的发表，也清将其加入到[参考文献](#bibliography)中，具体详情请参见我们的[社区贡献指南](CONTRIBUTING.md)。\n\n#### 更多期待内容\n\n我们欢迎并期待社区开发者贡献以下几个方面的内容：\n\n- Solidity代码测试（包括代码结构，程序框架 以及 常见软件工程测试）\n- 智能合约开发经验总结，以及更广泛的基于区块链的开发技巧分享\n\n## 基本理念\n\n<a name=\"general-philosophy\"></a>\n\n以太坊和其他复杂的区块链项目都处于早期阶段并且有很强的实验性质。因此，随着新的bug和安全漏洞被发现，新的功能不断被开发出来，其面临的安全威胁也是不断变化的。这篇文章对于开发人员编写安全的智能合约来说只是个开始。\n\n开发智能合约需要一个全新的工程思维，它不同于我们以往项目的开发。因为它犯错的代价是巨大的，并且很难像传统软件那样轻易的打上补丁。就像直接给硬件编程或金融服务类软件开发，相比于web开发和移动开发都有更大的挑战。因此，仅仅防范已知的漏洞是不够的，你还需要学习新的开发理念：\n\n- **对可能的错误有所准备**。任何有意义的智能合约或多或少都存在错误。因此你的代码必须能够正确的处理出现的bug和漏洞。始终保证以下规则：\n\n  - 当智能合约出现错误时，停止合约，（“断路开关”）\n  - 管理账户的资金风险（限制（转账）速率、最大（转账）额度）\n  - 有效的途径来进行bug修复和功能提升\n\n- [**谨慎发布智能合约**](#contract-rollout)。 尽量在正式发布智能合约之前发现并修复可能的bug。\n\n  - 对智能合约进行彻底的测试，并在任何新的攻击手法被发现后及时的测试(包括已经发布的合约)\n  - 从alpha版本在测试网（testnet）上发布开始便提供[bug赏金计划](#bounties)\n  - 阶段性发布，每个阶段都提供足够的测试\n\n- **保持智能合约的简洁**。复杂会增加出错的风险。\n\n  - 确保智能合约逻辑简洁\n  - 确保合约和函数模块化\n  - 使用已经被广泛使用的合约或工具（比如，不要自己写一个随机数生成器）\n  - 条件允许的话，清晰明了比性能更重要\n  - 只在你系统的去中心化部分使用区块链\n\n- **保持更新**。通过下一章节所列出的资源来确保获取到最新的安全进展。\n\n  - 在任何新的漏洞被发现时检查你的智能合约\n  - 尽可能快的将使用到的库或者工具更新到最新\n  - 使用最新的安全技术\n\n- **清楚区块链的特性**。尽管你先前所拥有的编程经验同样适用于以太坊开发，但这里仍然有些陷阱你需要留意：\n\n  - 特别小心针对外部合约的调用，因为你可能执行的是一段恶意代码然后更改控制流程\n  - 清楚你的public function是公开的，意味着可以被恶意调用。（在以太坊上）你的private data也是对他人可见的\n  - 清楚gas的花费和区块的gas limit\n\n### 基本权衡：简单性与复杂性\n\n<a name=\"fundamental-tradeoffs\"></a>\n\n在评估一个智能合约的架构和安全性时有很多需要权衡的地方。对任何智能合约的建议是在各个权衡点中找到一个平衡点。\n\n从传统软件工程的角度出发：一个理想的智能合约首先需要模块化，能够重用代码而不是重复编写，并且支持组件升级。从智能合约安全架构的角度出发同样如此，模块化和重用被严格审查检验过的合约是最佳策略，特别是在复杂智能合约系统里。\n\n然而，这里有几个重要的例外，它们从合约安全和传统软件工程两个角度考虑，所得到的重要性排序可能不同。当中每一条，都需要针对智能合约系统的特点找到最优的组合方式来达到平衡。\n\n- 固化 vs 可升级\n- 一体化 vs 模块化\n- 重复 vs 可重用\n\n#### 固化 vs 可升级\n\n在很多文档或者开发指南中，包括该指南，都会强调延展性比如：可终止，可升级或可更改的特性，不过对于智能合约来说，延展性和安全之间是个*基本权衡*。\n\n延展性会增加程序复杂性和潜在的攻击面。对于那些只在特定的时间段内提供有限的功能的智能合约，简单性比复杂性显得更加高效，比如无管治功能，有限短期内使用的代币发行的智能合约系统(governance-fee,finite-time-frame token-sale contracts)。\n\n#### 一体化 vs 模块化\n\n一个一体化的独立的智能合约把所有的变量和模块都放到一个合约中。尽管只有少数几个大家熟知的智能合约系统真的做到了大体量，但在将数据和流程都放到一个合约中还是享有部分优点--比如，提高代码审核(code review)效率。\n\n和在这里讨论的其他权衡点一样，传统软件开发策略和从合约安全角度出发考虑，两者不同主要在对于简单、短生命周期的智能合约；对于更复杂、长生命周期的智能合约，两者策略理念基本相同。\n\n#### 重复 vs 可重用\n\n从软件工程角度看，智能合约系统希望在合理的情况下最大程度地实现重用。 在Solidity中重用合约代码有很多方法。 使用**你拥有的**以前部署的经过验证的智能合约是实现代码重用的最安全的方式。\n\n在以前所拥有已部署智能合约不可重用时重复还是很需要的。 现在[Live Libs](https://github.com/ConsenSys/live-libs) 和[Zeppelin Solidity](https://github.com/OpenZeppelin/zeppelin-solidity) 正寻求提供安全的智能合约组件使其能够被重用而不需要每次都重新编写。任何合约安全性分析都必须标明重用代码，特别是以前没有建立与目标智能合同系统中处于风险中的资金相称的信任级别的代码。\n\n## 安全通知\n\n以下这些地方通常会通报在Ethereum或Solidity中新发现的漏洞。安全通告的官方来源是Ethereum Blog，但是一般漏洞都会在其他地方先被披露和讨论。\n\n- [Ethereum Blog](https://blog.ethereum.org/): The official Ethereum blog\n  - [Ethereum Blog - Security only](https://blog.ethereum.org/category/security/): 所有相关博客都带有**Security**标签\n- [Ethereum Gitter](https://gitter.im/orgs/ethereum/rooms) 聊天室\n  - [Solidity](https://gitter.im/ethereum/solidity)\n  - [Go-Ethereum](https://gitter.im/ethereum/go-ethereum)\n  - [CPP-Ethereum](https://gitter.im/ethereum/cpp-ethereum)\n  - [Research](https://gitter.im/ethereum/research)\n- [Reddit](https://www.reddit.com/r/ethereum)\n- [Network Stats](https://ethstats.net/)\n\n强烈建议你经常浏览这些网站，尤其是他们提到的可能会影响你的智能合约的漏洞。\n\n另外, 这里列出了以太坊参与安全模块相关的核心开发成员, 浏览 [bibliography](https://github.com/ConsenSys/smart-contract-best-practices#smart-contract-security-bibliography) 获取更多信息。\n\n- **Vitalik Buterin**: [Twitter](https://twitter.com/vitalikbuterin), [Github](https://github.com/vbuterin), [Reddit](https://www.reddit.com/user/vbuterin), [Ethereum Blog](https://blog.ethereum.org/author/vitalik-buterin/)\n- **Dr. Christian Reitwiessner**: [Twitter](https://twitter.com/ethchris), [Github](https://github.com/chriseth), [Ethereum Blog](https://blog.ethereum.org/author/christian_r/)\n- **Dr. Gavin Wood**: [Twitter](https://twitter.com/gavofyork), [Blog](http://gavwood.com/), [Github](https://github.com/gavofyork)\n- **Vlad Zamfir**: [Twitter](https://twitter.com/vladzamfir), [Github](https://github.com/vladzamfir), [Ethereum Blog](https://blog.ethereum.org/author/vlad/)\n\n除了关注核心开发成员，参与到各个区块链安全社区也很重要，因为安全漏洞的披露或研究将通过各方进行。\n<a name=\"solidity-tips\"></a>\n\n## 关于使用Solidity开发的智能合约安全建议\n\n### 外部调用\n\n#### 尽量避免外部调用\n\n<a name=\"avoid-external-calls\"></a>\n\n调用不受信任的外部合约可能会引发一系列意外的风险和错误。外部调用可能在其合约和它所依赖的其他合约内执行恶意代码。因此，每一个外部调用都会有潜在的安全威胁，尽可能的从你的智能合约内移除外部调用。当无法完全去除外部调用时，可以使用这一章节其他部分提供的建议来尽量减少风险。\n\n<a name=\"send-vs-call-value\"></a>\n\n#### 仔细权衡“send()”、“transfer()”、以及“call.value()”\n\n当转账Ether时，需要仔细权衡“someAddress.send()”、“someAddress.transfer()”、和“someAddress.call.value()()”之间的差别。\n\n- `x.transfer(y)`和`if (!x.send(y)) throw;`是等价的。send是transfer的底层实现，建议尽可能直接使用transfer。\n- `someAddress.send()`和`someAddress.transfer()` 能保证[可重入](#reentrancy) **安全** 。\n  尽管这些外部智能合约的函数可以被触发执行，但补贴给外部智能合约的2,300 gas，意味着仅仅只够记录一个event到日志中。\n- `someAddress.call.value()()` 将会发送指定数量的Ether并且触发对应代码的执行。被调用的外部智能合约代码将享有所有剩余的gas，通过这种方式转账是很容易有可重入漏洞的，非常 **不安全**。\n\n使用`send()` 或`transfer()` 可以通过制定gas值来预防可重入， 但是这样做可能会导致在和合约调用fallback函数时出现问题，由于gas可能不足，而合约的fallback函数执行至少需要2,300 gas消耗。\n\n一种被称为[*push* 和*pull*](#favor-pull-over-push-payments)的 机制试图来平衡两者， 在 *push* 部分使用`send()` 或`transfer()`，在*pull* 部分使用`call.value()()`。（\\*译者注：在需要对外未知地址转账Ether时使用`send()` 或`transfer()`，已知明确内部无恶意代码的地址转账Ether使用`call.value()()`）\n\n需要注意的是使用`send()` 或`transfer()` 进行转账并不能保证该智能合约本身重入安全，它仅仅只保证了这次转账操作时重入安全的。\n\n<a name=\"handle-external-errors\"></a>\n\n#### 处理外部调用错误\n\nSolidity提供了一系列在raw address上执行操作的底层方法，比如： `address.call()`，`address.callcode()`， `address.delegatecall()`和`address.send`。这些底层方法不会抛出异常(throw)，只是会在遇到错误时返回false。另一方面， *contract calls* （比如，`ExternalContract.doSomething()`)）会自动传递异常，（比如，`doSomething()`抛出异常，那么`ExternalContract.doSomething()` 同样会进行`throw`） )。\n\n如果你选择使用底层方法，一定要检查返回值来对可能的错误进行处理。\n\n```sh\n// bad\nsomeAddress.send(55);\nsomeAddress.call.value(55)(); // this is doubly dangerous, as it will forward all remaining gas and doesn't check for result\nsomeAddress.call.value(100)(bytes4(sha3(\"deposit()\"))); // if deposit throws an exception, the raw call() will only return false and transaction will NOT be reverted\n\n// good\nif(!someAddress.send(55)) {\n    // Some failure code\n}\n\nExternalContract(someAddress).deposit.value(100);\n```\n\n<a name=\"expect-control-flow-loss\"></a>\n\n#### 不要假设你知道外部调用的控制流程\n\n无论是使用**raw calls** 或是**contract calls**，如果这个`ExternalContract`是不受信任的都应该假设存在恶意代码。即使`ExternalContract`不包含恶意代码，但它所调用的其他合约代码可能会包含恶意代码。一个具体的危险例子便是恶意代码可能会劫持控制流程导致竞态。（浏览[Race Conditions](https://github.com/ConsenSys/smart-contract-best-practices/#race-conditions)获取更多关于这个问题的讨论）\n\n<a name=\"favor-pull-over-push-payments\"></a>\n\n#### 对于外部合约优先使用*pull* 而不是*push*\n\n外部调用可能会有意或无意的失败。为了最小化这些外部调用失败带来的损失，通常好的做法是将外部调用函数与其余代码隔离，最终是由收款发起方负责发起调用该函数。这种做法对付款操作尤为重要，比如让用户自己撤回资产而不是直接发送给他们。（*译者注：事先设置需要付给某一方的资产的值，表明接收方可以从当前账户撤回资金的额度，然后由接收方调用当前合约提现函数完成转账*）。（这种方法同时也避免了造成 [gas limit相关问题](https://github.com/ConsenSys/smart-contract-best-practices/#dos-with-block-gas-limit)。）\n\n```sh\n// bad\ncontract auction {\n    address highestBidder;\n    uint highestBid;\n\n    function bid() payable {\n        if (msg.value < highestBid) throw;\n\n        if (highestBidder != 0) {\n            if (!highestBidder.send(highestBid)) { // if this call consistently fails, no one else can bid\n                throw;\n            }\n        }\n\n       highestBidder = msg.sender;\n       highestBid = msg.value;\n    }\n}\n\n// good\ncontract auction {\n    address highestBidder;\n    uint highestBid;\n    mapping(address => uint) refunds;\n\n    function bid() payable external {\n        if (msg.value < highestBid) throw;\n\n        if (highestBidder != 0) {\n            refunds[highestBidder] += highestBid; // record the refund that this user can claim\n        }\n\n        highestBidder = msg.sender;\n        highestBid = msg.value;\n    }\n\n    function withdrawRefund() external {\n        uint refund = refunds[msg.sender];\n        refunds[msg.sender] = 0;\n        if (!msg.sender.send(refund)) {\n            refunds[msg.sender] = refund; // reverting state because send failed\n        }\n    }\n}\n```\n\n<a name=\"mark-untrusted-contracts\"></a>\n\n#### 标记不受信任的合约\n\n当你自己的函数调用外部合约时，你的变量、方法、合约接口命名应该表明和他们可能是不安全的。\n\n```sh\n// bad\nBank.withdraw(100); // Unclear whether trusted or untrusted\n\nfunction makeWithdrawal(uint amount) { // Isn't clear that this function is potentially unsafe\n    Bank.withdraw(amount);\n}\n\n// good\nUntrustedBank.withdraw(100); // untrusted external call\nTrustedBank.withdraw(100); // external but trusted bank contract maintained by XYZ Corp\n\nfunction makeUntrustedWithdrawal(uint amount) {\n    UntrustedBank.withdraw(amount);\n}\n```\n\n### 使用`assert()`强制不变性\n\n当断言条件不满足时将触发断言保护 -- 比如不变的属性发生了变化。举个例子，代币在以太坊上的发行比例，在代币的发行合约里可以通过这种方式得到解决。断言保护经常需要和其他技术组合使用，比如当断言被触发时先挂起合约然后升级。（否则将一直触发断言，你将陷入僵局）\n\n例如：\n\n```\ncontract Token {\n    mapping(address => uint) public balanceOf;\n    uint public totalSupply;\n\n    function deposit() public payable {\n        balanceOf[msg.sender] += msg.value;\n        totalSupply += msg.value;\n        assert(address(this).balance >= totalSupply);\n    }\n}\n```\n\n注意断言保护 **不是** 严格意义的余额检测， 因为智能合约可以不通过`deposit()` 函数被 [强制发送Ether](#ether-forcibly-sent)！\n\n### 正确使用`assert()`和`require()`\n\n在Solidity 0.4.10 中`assert()`和`require()`被加入。`require(condition)`被用来验证用户的输入，如果条件不满足便会抛出异常，应当使用它验证所有用户的输入。 `assert(condition)` 在条件不满足也会抛出异常，但是最好只用于固定变量：内部错误或你的智能合约陷入无效的状态。遵循这些范例，使用分析工具来验证永远不会执行这些无效操作码：意味着代码中不存在任何不变量，并且代码已经正式验证。\n\n<a name=\"beware-rounding-with-integer-division\"></a>\n\n### 小心整数除法的四舍五入\n\n所有整数除数都会四舍五入到最接近的整数。 如果您需要更高精度，请考虑使用乘数，或存储分子和分母。\n\n（将来Solidity会有一个fixed-point类型来让这一切变得容易。）\n\n```sh\n// bad\nuint x = 5 / 2; // Result is 2, all integer divison rounds DOWN to the nearest integer\n\n// good\nuint multiplier = 10;\nuint x = (5 * multiplier) / 2;\n\nuint numerator = 5;\nuint denominator = 2;\n```\n\n<a name=\"ether-forcibly-sent\"></a>\n\n### 记住Ether可以被强制发送到账户\n\n谨慎编写用来检查账户余额的不变量。\n\n攻击者可以强制发送wei到任何账户，而且这是不能被阻止的（即使让fallback函数`throw`也不行）\n\n攻击者可以仅仅使用1 wei来创建一个合约，然后调用`selfdestruct(victimAddress)`。在`victimAddress`中没有代码被执行，所以这是不能被阻止的。\n\n### 不要假设合约创建时余额为零\n\n攻击者可以在合约创建之前向合约的地址发送wei。合约不能假设它的初始状态包含的余额为零。浏览[issue 61](https://github.com/ConsenSys/smart-contract-best-practices/issues/61) 获取更多信息。\n\n### 记住链上的数据是公开的\n\n许多应用需要提交的数据是私有的，直到某个时间点才能工作。游戏（比如，链上游戏rock-paper-scissors（石头剪刀布））和拍卖机（比如，sealed-bid second-price auctions）是两个典型的例子。如果你的应用存在隐私保护问题，一定要避免过早发布用户信息。\n\n例如：\n\n- 在游戏石头剪刀布中，需要参与游戏的双方提交他们“行动计划”的hash值，然后需要双方随后提交他们的行动计划；如果双方的“行动计划”和先前提交的hash值对不上则抛出异常。\n- 在拍卖中，要求玩家在初始阶段提交其所出价格的hash值（以及超过其出价的保证金），然后在第二阶段提交他们所出价格的资金。\n- 当开发一个依赖随机数生成器的应用时，正确的顺序应当是（1）玩家提交行动计划，（2）生成随机数，（3）玩家支付。产生随机数是一个值得研究的领域；当前最优的解决方案包括比特币区块头（通过http://btcrelay.org验证），hash-commit-reveal方案（比如，一方产生number后，将其散列值提交作为对这个number的“提交”，然后在随后再暴露这个number本身）和 [RANDAO](http://github.com/randao/randao)。\n- 如果你正在实现频繁的批量拍卖，那么hash-commit机制也是个不错的选择。\n\n### 权衡Abstract合约和Interfaces\n\nInterfaces和Abstract合约都是用来使智能合约能更好的被定制和重用。Interfaces是在Solidity 0.4.11中被引入的，和Abstract合约很像但是不能定义方法只能申明。Interfaces存在一些限制比如不能够访问storage或者从其他Interfaces那继承，通常这些使Abstract合约更实用。尽管如此，Interfaces在实现智能合约之前的设计智能合约阶段仍然有很大用处。另外，需要注意的是如果一个智能合约从另一个Abstract合约继承而来那么它必须实现所有Abstract合约内的申明并未实现的函数，否则它也会成为一个Abstract合约。\n\n### 在双方或多方参与的智能合约中，参与者可能会“脱机离线”后不再返回\n\n不要让退款和索赔流程依赖于参与方执行的某个特定动作而没有其他途径来获取资金。比如，在石头剪刀布游戏中，一个常见的错误是在两个玩家提交他们的行动计划之前不要付钱。然而一个恶意玩家可以通过一直不提交它的行动计划来使对方蒙受损失 -- 事实上，如果玩家看到其他玩家泄露的行动计划然后决定他是否会损失（译者注：发现自己输了），那么他完全有理由不再提交他自己的行动计划。这些问题也同样会出现在通道结算。当这些情形出现导致问题后：（1）提供一种规避非参与者和参与者的方式，可能通过设置时间限制，和（2）考虑为参与者提供额外的经济激励，以便在他们应该这样做的所有情况下仍然提交信息。\n\n<a name=\"keep-fallback-functions-simple\"></a>\n\n### 使Fallback函数尽量简单\n\n[Fallback函数](http://solidity.readthedocs.io/en/latest/contracts.html#fallback-function)在合约执行消息发送没有携带参数（或当没有匹配的函数可供调用）时将会被调用，而且当调用 `.send()` or `.transfer()`时，只会有2,300 gas 用于失败后fallback函数的执行（*译者注：合约收到Ether也会触发fallback函数执行*）。如果你希望能够监听`.send（）`或`.transfer（）`接收到Ether，则可以在fallback函数中使用event（译者注：让客户端监听相应事件做相应处理）。谨慎编写fallback函数以免gas不够用。\n\n```sh\n// bad\nfunction() payable { balances[msg.sender] += msg.value; }\n\n// good\nfunction deposit() payable external { balances[msg.sender] += msg.value; }\n\nfunction() payable { LogDepositReceived(msg.sender); }\n```\n\n<a name=\"mark-visibility\"></a>\n\n### 明确标明函数和状态变量的可见性\n\n明确标明函数和状态变量的可见性。函数可以声明为 `external`，`public`， `internal` 或 `private`。 分清楚它们之间的差异， 例如`external` 可能已够用而不是使用 `public`。对于状态变量，`external`是不可能的。明确标注可见性将使得更容易避免关于谁可以调用该函数或访问变量的错误假设。\n\n```sh\n// bad\nuint x; // the default is private for state variables, but it should be made explicit\nfunction buy() { // the default is public\n    // public code\n}\n\n// good\nuint private y;\nfunction buy() external {\n    // only callable externally\n}\n\nfunction utility() public {\n    // callable externally, as well as internally: changing this code requires thinking about both cases.\n}\n\nfunction internalAction() internal {\n    // internal code\n}\n```\n\n<a name=\"lock-pragmas\"></a>\n\n### 将程序锁定到特定的编译器版本\n\n智能合约应该应该使用和它们测试时使用最多的编译器相同的版本来部署。锁定编译器版本有助于确保合约不会被用于最新的可能还有bug未被发现的编译器去部署。智能合约也可能会由他人部署，而pragma标明了合约作者希望使用哪个版本的编译器来部署合约。\n\n```sh\n// bad\npragma solidity ^0.4.4;\n\n\n// good\npragma solidity 0.4.4;\n```\n\n<a name=\"beware-division-by-zero\"></a>\n\n（*译者注：这当然也会付出兼容性的代价*）\n\n### 小心分母为零 (Solidity \\< 0.4)\n\n早于0.4版本, 当一个数尝试除以零时，Solidity [返回zero](https://github.com/ethereum/solidity/issues/670) 并没有 `throw` 一个异常。确保你使用的Solidity版本至少为 0.4。\n\n<a name=\"differentiate-functions-events\"></a>\n\n### 区分函数和事件\n\n为了防止函数和事件（Event）产生混淆，命名一个事件使用大写并加入前缀（我们建议**LOG**）。对于函数， 始终以小写字母开头，构造函数除外。\n\n```sh\n// bad\nevent Transfer() {}\nfunction transfer() {}\n\n// good\nevent LogTransfer() {}\nfunction transfer() external {}\n```\n\n<a name=\"prefer-newer-constructs\"></a>\n\n### 使用Solidity更新的构造器\n\n更合适的构造器/别名，如`selfdestruct`（旧版本为`suicide`）和`keccak256`（旧版本为`sha3`）。 像`require(msg.sender.send(1 ether))`的模式也可以简化为使用`transfer()`，如`msg.sender.transfer(1 ether)`。\n\n<a name=\"known-attacks\"></a>\n\n## 已知的攻击\n\n<a name=\"race-conditions\"></a>\n\n### 竞态<sup><a href='#footnote-race-condition-terminology'>\\*</a></sup>\n\n调用外部合约的主要危险之一是它们可以接管控制流，并对调用函数意料之外的数据进行更改。 这类bug有多种形式，导致DAO崩溃的两个主要错误都是这种错误。\n\n<a name=\"reentrancy\"></a>\n\n#### 重入\n\n这个版本的bug被注意到是其可以在第一次调用这个函数完成之前被多次重复调用。对这个函数不断的调用可能会造成极大的破坏。\n\n```sh\n// INSECURE\nmapping (address => uint) private userBalances;\n\nfunction withdrawBalance() public {\n    uint amountToWithdraw = userBalances[msg.sender];\n    if (!(msg.sender.call.value(amountToWithdraw)())) { throw; } // At this point, the caller's code is executed, and can call withdrawBalance again\n    userBalances[msg.sender] = 0;\n}\n```\n\n（*译者注：使用msg.sender.call.value()()）传递给fallback函数可用的gas是当前剩余的所有gas，在这里，假如从你账户执行提现操作的恶意合约的fallback函数内递归调用你的withdrawBalance()便可以从你的账户转走更多的币。*）\n\n可以看到当调msg.sender.call.value()()时，并没有将userBalances\\[msg.sender\\] 清零，于是在这之前可以成功递归调用很多次withdrawBalance()函数。 一个非常相像的bug便是出现在针对 DAO 的攻击。\n\n在给出来的例子中，最好的方法是 [ 使用 `send()` 而不是`call.value()()`](https://github.com/ConsenSys/smart-contract-best-practices#send-vs-call-value)。这将避免多余的代码被执行。\n\n然而，如果你没法完全移除外部调用，另一个简单的方法来阻止这个攻击是确保你在完成你所有内部工作之前不要进行外部调用：\n\n```sh\nmapping (address => uint) private userBalances;\n\nfunction withdrawBalance() public {\n    uint amountToWithdraw = userBalances[msg.sender];\n    userBalances[msg.sender] = 0;\n    if (!(msg.sender.call.value(amountToWithdraw)())) { throw; } // The user's balance is already 0, so future invocations won't withdraw anything\n}\n```\n\n注意如果你有另一个函数也调用了 `withdrawBalance()`， 那么这里潜在的存在上面的攻击，所以你必须认识到任何调用了不受信任的合约代码的合约也是不受信任的。继续浏览下面的相关潜在威胁解决办法的讨论。\n\n#### 跨函数竞态\n\n攻击者也可以使用两个共享状态变量的不同的函数来进行类似攻击。\n\n```sh\n// INSECURE\nmapping (address => uint) private userBalances;\n\nfunction transfer(address to, uint amount) {\n    if (userBalances[msg.sender] >= amount) {\n       userBalances[to] += amount;\n       userBalances[msg.sender] -= amount;\n    }\n}\n\nfunction withdrawBalance() public {\n    uint amountToWithdraw = userBalances[msg.sender];\n    if (!(msg.sender.call.value(amountToWithdraw)())) { throw; } // At this point, the caller's code is executed, and can call transfer()\n    userBalances[msg.sender] = 0;\n}\n```\n\n着这个例子中，攻击者在他们外部调用`withdrawBalance`函数时调用`transfer()`，如果这个时候`withdrawBalance`还没有执行到`userBalances[msg.sender] = 0;`这里，那么他们的余额就没有被清零，那么他们就能够调用`transfer()`转走代币尽管他们其实已经收到了代币。这个弱点也可以被用到对DAO的攻击。\n\n同样的解决办法也会管用，在执行转账操作之前先清零。也要注意在这个例子中所有函数都是在同一个合约内。然而，如果这些合约共享了状态，同样的bug也可以发生在跨合约调用中。\n\n#### 竞态解决办法中的陷阱\n\n由于竞态既可以发生在跨函数调用，也可以发生在跨合约调用，任何只是避免重入的解决办法都是不够的。\n\n作为替代，我们建议首先应该完成所有内部的工作然后再执行外部调用。这个规则可以避免竞态发生。然而，你不仅应该避免过早调用外部函数而且应该避免调用那些也调用了外部函数的外部函数。例如，下面的这段代码是不安全的：\n\n```sh\n// INSECURE\nmapping (address => uint) private userBalances;\nmapping (address => bool) private claimedBonus;\nmapping (address => uint) private rewardsForA;\n\nfunction withdraw(address recipient) public {\n    uint amountToWithdraw = userBalances[recipient];\n    rewardsForA[recipient] = 0;\n    if (!(recipient.call.value(amountToWithdraw)())) { throw; }\n}\n\nfunction getFirstWithdrawalBonus(address recipient) public {\n    if (claimedBonus[recipient]) { throw; } // Each recipient should only be able to claim the bonus once\n\n    rewardsForA[recipient] += 100;\n    withdraw(recipient); // At this point, the caller will be able to execute getFirstWithdrawalBonus again.\n    claimedBonus[recipient] = true;\n}\n```\n\n尽管`getFirstWithdrawalBonus()` 没有直接调用外部合约，但是它调用的`withdraw()` 却会导致竞态的产生。在这里你不应该认为`withdraw()`是受信任的。\n\n```sh\nmapping (address => uint) private userBalances;\nmapping (address => bool) private claimedBonus;\nmapping (address => uint) private rewardsForA;\n\nfunction untrustedWithdraw(address recipient) public {\n    uint amountToWithdraw = userBalances[recipient];\n    rewardsForA[recipient] = 0;\n    if (!(recipient.call.value(amountToWithdraw)())) { throw; }\n}\n\nfunction untrustedGetFirstWithdrawalBonus(address recipient) public {\n    if (claimedBonus[recipient]) { throw; } // Each recipient should only be able to claim the bonus once\n\n    claimedBonus[recipient] = true;\n    rewardsForA[recipient] += 100;\n    untrustedWithdraw(recipient); // claimedBonus has been set to true, so reentry is impossible\n}\n```\n\n除了修复bug让重入不可能成功，[不受信任的函数也已经被标记出来](https://github.com/ConsenSys/smart-contract-best-practices#mark-untrusted-contracts) 。同样的情景： `untrustedGetFirstWithdrawalBonus()` 调用`untrustedWithdraw()`, 而后者调用了外部合约，因此在这里`untrustedGetFirstWithdrawalBonus()` 是不安全的。\n\n另一个经常被提及的解决办法是（*译者注：像传统多线程编程中一样*）使用[mutex](https://en.wikipedia.org/wiki/Mutual_exclusion)。它会\"lock\" 当前状态，只有锁的当前拥有者能够更改当前状态。一个简单的例子如下：\n\n```sh\n// Note: This is a rudimentary example, and mutexes are particularly useful where there is substantial logic and/or shared state\nmapping (address => uint) private balances;\nbool private lockBalances;\n\nfunction deposit() payable public returns (bool) {\n    if (!lockBalances) {\n        lockBalances = true;\n        balances[msg.sender] += msg.value;\n        lockBalances = false;\n        return true;\n    }\n    throw;\n}\n\nfunction withdraw(uint amount) payable public returns (bool) {\n    if (!lockBalances && amount > 0 && balances[msg.sender] >= amount) {\n        lockBalances = true;\n\n        if (msg.sender.call(amount)()) { // Normally insecure, but the mutex saves it\n          balances[msg.sender] -= amount;\n        }\n\n        lockBalances = false;\n        return true;\n    }\n\n    throw;\n}\n```\n\n如果用户试图在第一次调用结束前第二次调用 `withdraw()`，将会被锁住。 这看上去很有效果，但当你使用多个合约互相交互时问题变得严峻了。 下面是一段不安全的代码：\n\n```\n// INSECURE\ncontract StateHolder {\n    uint private n;\n    address private lockHolder;\n\n    function getLock() {\n        if (lockHolder != 0) { throw; }\n        lockHolder = msg.sender;\n    }\n\n    function releaseLock() {\n        lockHolder = 0;\n    }\n\n    function set(uint newState) {\n        if (msg.sender != lockHolder) { throw; }\n        n = newState;\n    }\n}\n```\n\n攻击者可以只调用`getLock()`，然后就不再调用 `releaseLock()`。如果他们真这样做，那么这个合约将会被永久锁住，任何接下来的操作都不会发生了。如果你使用mutexs来避免竞态，那么一定要确保没有地方能够打断锁的进程或绝不释放锁。（这里还有一个潜在的威胁，比如死锁和活锁。在你决定使用锁之前最好大量阅读相关文献（*译者注：这是真的，传统的在多线程环境下对锁的使用一直是个容易犯错的地方*））\n\n<a name=\"footnote-race-condition-terminology\"></a>\n\n<div style='font-size: 80%; display: inline;'>* 有些人可能会发反对使用该术语 <i>竞态</i>，因为以太坊并没有真正意思上实现并行执行。然而在逻辑上依然存在对资源的竞争，同样的陷阱和潜在的解决方案。 </div>\n\n<a name=\"transaction-ordering-dependence\"></a>\n\n### 交易顺序依赖(TOD) / 前面的先运行\n\n以上是涉及攻击者在**单个交易**内执行恶意代码产生竞态的示例。接下来演示在区块链本身运作原理导致的竞态：（同一个block内的）交易顺序很容易受到操纵。\n\n由于交易在短暂的时间内会先存放到mempool中，所以在矿工将其打包进block之前，是可以知道会发生什么动作的。这对于一个去中心化的市场来说是麻烦的，因为可以查看到代币的交易信息，并且可以在它被打包进block之前改变交易顺序。避免这一点很困难，因为它归结为具体的合同本身。例如，在市场上，最好实施批量拍卖（这也可以防止高频交易问题）。 另一种使用预提交方案的方法（“我稍后会提供详细信息”）。\n\n<a name=\"timestamp-dependence\"></a>\n\n### 时间戳依赖\n\n请注意，块的时间戳可以由矿工操纵，并且应考虑时间戳的所有直接和间接使用。 **区块数量**和**平均出块时间**可用于估计时间，但这不是区块时间在未来可能改变（例如Casper期望的更改）的证明。\n\n```sh\nuint someVariable = now + 1;\n\nif (now % 2 == 0) { // the now can be manipulated by the miner\n\n}\n\nif ((someVariable - 100) % 2 == 0) { // someVariable can be manipulated by the miner\n\n}\n```\n\n<a name=\"integer-overflow-and-underflow\"></a>\n\n### 整数上溢和下溢\n\n这里大概有 [20关于上溢和下溢的例子](https://github.com/ethereum/solidity/issues/796#issuecomment-253578925)。\n\n考虑如下这个简单的转账操作：\n\n```sh\nmapping (address => uint256) public balanceOf;\n\n// INSECURE\nfunction transfer(address _to, uint256 _value) {\n    /* Check if sender has balance */\n    if (balanceOf[msg.sender] < _value)\n        throw;\n    /* Add and subtract new balances */\n    balanceOf[msg.sender] -= _value;\n    balanceOf[_to] += _value;\n}\n\n// SECURE\nfunction transfer(address _to, uint256 _value) {\n    /* Check if sender has balance and for overflows */\n    if (balanceOf[msg.sender] < _value || balanceOf[_to] + _value < balanceOf[_to])\n        throw;\n\n    /* Add and subtract new balances */\n    balanceOf[msg.sender] -= _value;\n    balanceOf[_to] += _value;\n}\n```\n\n如果余额到达**uint**的最大值（2^256），便又会变为0。应当检查这里。溢出是否与之相关取决于具体的实施方式。想想uint值是否有机会变得这么大或和谁会改变它的值。如果任何用户都有权利更改uint的值，那么它将更容易受到攻击。如果只有管理员能够改变它的值，那么它可能是安全的，因为没有别的办法可以跨越这个限制。\n\n对于下溢同样的道理。如果一个uint别改变后小于0，那么将会导致它下溢并且被设置成为最大值（2^256）。\n\n对于较小数字的类型比如uint8、uint16、uint24等也要小心：他们更加容易达到最大值。\n\n<a name=\"dos-with-unexpected-throw\"></a>\n\n### 通过(Unexpected) Throw发动DoS\n\n考虑如下简单的智能合约：\n\n```sh\n// INSECURE\ncontract Auction {\n    address currentLeader;\n    uint highestBid;\n\n    function bid() payable {\n        if (msg.value <= highestBid) { throw; }\n\n        if (!currentLeader.send(highestBid)) { throw; } // Refund the old leader, and throw if it fails\n\n        currentLeader = msg.sender;\n        highestBid = msg.value;\n    }\n}\n```\n\n当有更高竞价时，它将试图退款给曾经最高竞价人，如果退款失败则会抛出异常。这意味着，恶意投标人可以成为当前最高竞价人，同时确保对其地址的任何退款**始终**失败。这样就可以阻止任何人调用“bid()”函数，使自己永远保持领先。建议向之前所说的那样建立[基于pull的支付系统](https://github.com/ConsenSys/smart-contract-best-practices/#favor-pull-over-push-payments) 。\n\n另一个例子是合约可能通过数组迭代来向用户支付（例如，众筹合约中的支持者）时。 通常要确保每次付款都成功。 如果没有，应该抛出异常。 问题是，如果其中一个支付失败，您将恢复整个支付系统，这意味着该循环将永远不会完成。 因为一个地址没有转账成功导致其他人都没得到报酬。\n\n```sh\naddress[] private refundAddresses;\nmapping (address => uint) public refunds;\n\n// bad\nfunction refundAll() public {\n    for(uint x; x < refundAddresses.length; x++) { // arbitrary length iteration based on how many addresses participated\n        if(refundAddresses[x].send(refunds[refundAddresses[x]])) {\n            throw; // doubly bad, now a single failure on send will hold up all funds\n        }\n    }\n}\n```\n\n再一次强调，同样的解决办法： [优先使用pull 而不是push支付系统](#favor-pull-over-push-payments)。\n\n<a name=\"dos-with-block-gas-limit\"></a>\n\n### 通过区块Gas Limit发动DoS\n\n在先前的例子中你可能已经注意到另一个问题：一次性向所有人转账，很可能会导致达到以太坊区块gas limit的上限。以太坊规定了每一个区块所能花费的gas limit，如果超过你的交易便会失败。\n\n即使没有故意的攻击，这也可能导致问题。然而，最为糟糕的是如果gas的花费被攻击者操控。在先前的例子中，如果攻击者增加一部分收款名单，并设置每一个收款地址都接收少量的退款。这样一来，更多的gas将会被花费从而导致达到区块gas limit的上限，整个转账的操作也会以失败告终。\n\n又一次证明了 [优先使用pull 而不是push支付系统](#favor-pull-over-push-payments)。\n\n如果你实在必须通过遍历一个变长数组来进行转账，最好估计完成它们大概需要多少个区块以及多少笔交易。然后你还必须能够追踪得到当前进行到哪以便当操作失败时从那里开始恢复，举个例子：\n\n```sh\nstruct Payee {\n    address addr;\n    uint256 value;\n}\nPayee payees[];\nuint256 nextPayeeIndex;\n\nfunction payOut() {\n    uint256 i = nextPayeeIndex;\n    while (i < payees.length && msg.gas > 200000) {\n      payees[i].addr.send(payees[i].value);\n      i++;\n    }\n    nextPayeeIndex = i;\n}\n```\n\n如上所示，你必须确保在下一次执行`payOut()`之前另一些正在执行的交易不会发生任何错误。如果必须，请使用上面这种方式来处理。\n\n<a name=\"call-depth-attack\"></a>\n\n### ~~Call Depth攻击~~\n\n由于[EIP 150](https://github.com/ethereum/EIPs/issues/150) 进行的硬分叉，Call Depth攻击已经无法实施<sup><a href='http://ethereum.stackexchange.com/questions/9398/how-does-eip-150-change-the-call-depth-attack'>\\*</a></sup> （由于以太坊限制了Call Depth最大为1024，确保了在达到最大深度之前gas都能被正确使用）\n\n<a name=\"eng-techniques\"></a>\n\n## 软件工程开发技巧\n\n正如我们先前在[基本理念](#general-philosophy) 章节所讨论的那样，避免自己遭受已知的攻击是不够的。由于在链上遭受攻击损失是巨大的，因此你还必须改变你编写软件的方式来抵御各种攻击。\n\n我们倡导“时刻准备失败\"，提前知道你的代码是否安全是不可能的。然而，我们可以允许合约以可预知的方式失败，然后最小化失败带来的损失。本章将带你了解如何为可预知的失败做准备。\n\n注意：当你向你的系统添加新的组件时总是伴随着风险的。一个不良设计本身会成为漏洞-一些精心设计的组件在交互过程中同样会出现漏洞。仔细考虑你在合约里使用的每一项技术，以及如何将它们整合共同创建一个稳定可靠的系统。\n\n### 升级有问题的合约\n\n如果代码中发现了错误或者需要对某些部分做改进都需要更改代码。在以太坊上发现一个错误却没有办法处理他们是太多意义的。\n\n关于如何在以太坊上设计一个合约升级系统是一个正处于积极研究的领域，在这篇文章当中我们没法覆盖所有复杂的领域。然而，这里有两个通用的基本方法。最简单的是专门设计一个注册合约，在注册合约中保存最新版合约的地址。对于合约使用者来说更能实现无缝衔接的方法是设计一个合约，使用它转发调用请求和数据到最新版的合约。\n\n无论采用何种技术，组件之间都要进行模块化和良好的分离，由此代码的更改才不会破坏原有的功能，造成孤儿数据，或者带来巨大的成本。 尤其是将复杂的逻辑与数据存储分开，这样你在使用更改后的功能时不必重新创建所有数据。\n\n当需要多方参与决定升级代码的方式也是至关重要的。根据你的合约，升级代码可能会需要通过单个或多个受信任方参与投票决定。如果这个过程会持续很长时间，你就必须要考虑是否要换成一种更加高效的方式以防止遭受到攻击，例如[紧急停止或断路器](#circuit-breakers-pause-contract-functionality)。\n\n**Example 1：使用注册合约存储合约的最新版本**\n\n在这个例子中，调用没有被转发，因此用户必须每次在交互之前都先获取最新的合约地址。\n\n```sh\ncontract SomeRegister {\n    address backendContract;\n    address[] previousBackends;\n    address owner;\n\n    function SomeRegister() {\n        owner = msg.sender;\n    }\n\n    modifier onlyOwner() {\n        if (msg.sender != owner) {\n            throw;\n        }\n        _;\n    }\n    \n    function changeBackend(address newBackend) public\n    onlyOwner()\n    returns (bool)\n    {\n        if(newBackend != backendContract) {\n            previousBackends.push(backendContract);\n            backendContract = newBackend;\n            return true;\n        }\n\n        return false;\n    }\n}\n```\n\n这种方法有两个主要的缺点：\n\n1、用户必须始终查找当前合约地址，否则任何未执行此操作的人都可能会使用旧版本的合约\n2、在你替换了合约后你需要仔细考虑如何处理原合约中的数据\n\n另外一种方法是设计一个用来转发调用请求和数据到最新版的合约：\n\n**例2： [使用`DELEGATECALL`](http://ethereum.stackexchange.com/questions/2404/upgradeable-contracts) 转发数据和调用**\n\n```\ncontract Relay {\n    address public currentVersion;\n    address public owner;\n\n    modifier onlyOwner() {\n        if (msg.sender != owner) {\n            throw;\n        }\n        _;\n    }\n\n    function Relay(address initAddr) {\n        currentVersion = initAddr;\n        owner = msg.sender; // this owner may be another contract with multisig, not a single contract owner\n    }\n\n    function changeContract(address newVersion) public\n    onlyOwner()\n    {\n        currentVersion = newVersion;\n    }\n\n    function() {\n        if(!currentVersion.delegatecall(msg.data)) throw;\n    }\n}\n```\n\n这种方法避免了先前的问题，但也有自己的问题。它使得你必须在合约里小心的存储数据。如果新的合约和先前的合约有不同的存储层，你的数据可能会被破坏。另外，这个例子中的模式没法从函数里返回值，只负责转发它们，由此限制了它的适用性。（这里有一个[更复杂的实现](https://github.com/ownage-ltd/ether-router) 想通过内联汇编和返回大小的注册表来解决这个问题）\n\n无论你的方法如何，重要的是要有一些方法来升级你的合约，否则当被发现不可避免的错误时合约将没法使用。\n\n### 断路器（暂停合约功能）\n\n由于断路器在满足一定条件时将会停止执行，如果发现错误时可以使用断路器。例如，如果发现错误，大多数操作可能会在合约中被挂起，这是唯一的操作就是撤销。你可以授权给任何你受信任的一方，提供给他们触发断路器的能力，或者设计一个在满足某些条件时自动触发某个断路器的程序规则。\n\n例如：\n\n```\nbool private stopped = false;\naddress private owner;\n\nmodifier isAdmin() {\n    if(msg.sender != owner) {\n        throw;\n    }\n    _;\n}\n\nfunction toggleContractActive() isAdmin public\n{\n    // You can add an additional modifier that restricts stopping a contract to be based on another action, such as a vote of users\n    stopped = !stopped;\n}\n\nmodifier stopInEmergency { if (!stopped) _; }\nmodifier onlyInEmergency { if (stopped) _; }\n\nfunction deposit() stopInEmergency public\n{\n    // some code\n}\n\nfunction withdraw() onlyInEmergency public\n{\n    // some code\n}\n```\n\n### 速度碰撞（延迟合约动作）\n\n速度碰撞使动作变慢，所以如果发生了恶意操作便有时间恢复。例如，[The DAO](https://github.com/slockit/DAO/) 从发起分割DAO请求到真正执行动作需要27天。这样保证了资金在此期间被锁定在合约里，增加了系统的可恢复性。在DAO攻击事件中，虽然在速度碰撞给定的时间段内没有有效的措施可以采取，但结合我们其他的技术，它们是非常有效的。\n\n例如：\n\n```\nstruct RequestedWithdrawal {\n    uint amount;\n    uint time;\n}\n\nmapping (address => uint) private balances;\nmapping (address => RequestedWithdrawal) private requestedWithdrawals;\nuint constant withdrawalWaitPeriod = 28 days; // 4 weeks\n\nfunction requestWithdrawal() public {\n    if (balances[msg.sender] > 0) {\n        uint amountToWithdraw = balances[msg.sender];\n        balances[msg.sender] = 0; // for simplicity, we withdraw everything;\n        // presumably, the deposit function prevents new deposits when withdrawals are in progress\n\n        requestedWithdrawals[msg.sender] = RequestedWithdrawal({\n            amount: amountToWithdraw,\n            time: now\n        });\n    }\n}\n\nfunction withdraw() public {\n    if(requestedWithdrawals[msg.sender].amount > 0 && now > requestedWithdrawals[msg.sender].time + withdrawalWaitPeriod) {\n        uint amountToWithdraw = requestedWithdrawals[msg.sender].amount;\n        requestedWithdrawals[msg.sender].amount = 0;\n\n        if(!msg.sender.send(amountToWithdraw)) {\n            throw;\n        }\n    }\n}\n```\n\n### 速率限制\n\n速率限制暂停或需要批准进行实质性更改。 例如，只允许存款人在一段时间内提取总存款的一定数量或百分比（例如，1天内最多100个ether） - 该时间段内的额外提款可能会失败或需要某种特别批准。 或者将速率限制做在合约级别，合约期限内只能发出发送一定数量的代币。\n\n[浏览例程](https://gist.github.com/PeterBorah/110c331dca7d23236f80e69c83a9d58c#file-circuitbreaker-sol)\n\n<a name=\"contract-rollout\"></a>\n\n### 合约发布\n\n在将大量资金放入合约之前，合约应当进行大量的长时间的测试。\n\n至少应该：\n\n- 拥有100％测试覆盖率的完整测试套件（或接近它）\n- 在自己的testnet上部署\n- 在公共测试网上部署大量测试和错误奖励\n- 彻底的测试应该允许各种玩家与合约进行大规模互动\n- 在主网上部署beta版以限制风险总额\n\n##### 自动弃用\n\n在合约测试期间，你可以在一段时间后强制执行自动弃用以阻止任何操作继续进行。例如，alpha版本的合约工作几周，然后自动关闭所有除最终退出操作的操作。\n\n```\nmodifier isActive() {\n    if (block.number > SOME_BLOCK_NUMBER) {\n        throw;\n    }\n    _;\n}\n\nfunction deposit() public\nisActive() {\n    // some code\n}\n\nfunction withdraw() public {\n    // some code\n}\n\n```\n\n##### 限制每个用户/合约的Ether数量\n\n在早期阶段，你可以限制任何用户（或整个合约）的Ether数量 - 以降低风险。\n\n<a name=\"bounties\"> </a>\n\n### Bug赏金计划\n\n运行赏金计划的一些提示：\n\n- 决定赏金以哪一种代币分配（BTC和/或ETH）\n- 决定赏金奖励的预算总额\n- 从预算来看，确定三级奖励：\n  - 你愿意发放的最小奖励\n  - 通常可发放的最高奖励\n  - 设置额外的限额以避免非常严重的漏洞被发现\n- 确定赏金发放给谁（3是一个典型）\n- 核心开发人员应该是赏金评委之一\n- 当收到错误报告时，核心开发人员应该评估bug的严重性\n- 在这个阶段的工作应该在私有仓库进行，并且在Github上的issue板块提出问题\n- 如果这个bug需要被修复，开发人员应该在私有仓库编写测试用例来复现这个bug\n- 开发人员需要修复bug并编写额外测试代码进行测试确保所有测试都通过\n- 展示赏金猎人的修复；并将修复合并回公共仓库也是一种方式\n- 确定赏金猎人是否有任何关于修复的其他反馈\n- 赏金评委根据bug的*可能性*和*影响*来确定奖励的大小\n- 在整个过程中保持赏金猎人参与讨论，并确保赏金发放不会延迟\n\n有关三级奖励的例子，参见 [Ethereum's Bounty Program](https://bounty.ethereum.org)：\n\n> 奖励的价值将根据影响的严重程度而变化。 奖励轻微的“无害”错误从0.05 BTC开始。 主要错误，例如导致协商一致的问题，将获得最多5个BTC的奖励。 在非常严重的漏洞的情况下，更高的奖励是可能的（高达25 BTC）。\n\n## 安全相关的文件和程序\n\n当发布涉及大量资金或重要任务的合约时，必须包含适当的文档。有关安全性的文档包括：\n\n**规范和发布计划**\n\n- 规格说明文档，图表，状态机，模型和其他文档，帮助审核人员和社区了解系统打算做什么。\n- 许多bug从规格中就能找到，而且它们的修复成本最低。\n- 发布计划所涉及到的参考[这里](#contract-rollout)列出的详细信息和完成日期。\n\n**状态**\n\n- 当前代码被部署到哪里\n- 编译器版本，使用的标志以及用于验证部署的字节码的步骤与源代码匹配\n- 将用于不同阶段的编译器版本和标志\n- 部署代码的当前状态（包括未决问题，性能统计信息等）\n\n**已知问题**\n\n- 合约的主要风险 (例如， 你可能会丢掉所有的钱，黑客可能会通过投票支持某些结果)\n- 所有已知的错误/限制\n- 潜在的攻击和解决办法\n- 潜在的利益冲突（例如，筹集的Ether将纳入自己的腰包，像Slock.it与DAO一样）\n\n**历史记录**\n\n- 测试（包括使用统计，发现的错误，测试时间）\n- 已审核代码的人员（及其关键反馈）\n\n**程序**\n\n- 发现错误的行动计划（例如紧急情况选项，公众通知程序等）\n- 如果出现问题，就可以降级程序（例如，资金拥有者在被攻击之前的剩余资金占现在剩余资金的比例）\n- 负责任的披露政策（例如，在哪里报告发现的bug，任何bug赏金计划的规则）\n- 在失败的情况下的追索权（例如，保险，罚款基金，无追索权）\n\n**联系信息**\n\n- 发现问题后和谁联系\n- 程序员姓名和/或其他重要参与方的名称\n- 可以询问问题的论坛/聊天室\n\n## 安全工具\n\n- [Oyente](https://github.com/melonproject/oyente) - 根据[这篇文章](http://www.comp.nus.edu.sg/~loiluu/papers/oyente.pdf)分析Ethereum代码以找到常见的漏洞。\n- [solidity-coverage](https://github.com/sc-forks/solidity-coverage) - Solidity代码覆盖率测试\n- [Solgraph](https://github.com/raineorshine/solgraph) - 生成一个DOT图，显示了Solidity合约的功能控制流程，并highlight了潜在的安全漏洞。\n\n## Linters\n\nLinters通过约束代码风格和排版来提高代码质量，使代码更容易阅读和查看。\n\n- [Solium](https://github.com/duaraghav8/Solium) - 另一种Solidity linting。\n- [Solint](https://github.com/weifund/solint) - 帮助你实施代码一致性约定来避免你合约中的错误的Solidity linting\n- [Solcheck](https://github.com/federicobond/solcheck) - 用JS写的Solidity linter，（实现上）深受eslint的影响。\n\n## 将来的改进\n\n- **编辑器安全警告**：编辑器将很快能够实现醒常见的安全错误，而不仅仅是编译错误。 Solidity浏览器即将推出这些功能。\n- **新的能够被编译成EVM字节码的函数式编程语言**： 像Solidity这种函数式编程语言相比面向过程编程语言能够保证功能的不变性和编译时间检查。通过确定性行为来减少出现错误的风险。（更多相关信息请参阅 [这里](https://plus.google.com/u/0/events/cmqejp6d43n5cqkdl3iu0582f4k), Curry-Howard 一致性和线性逻辑）\n\n<a name=\"bibliography\"></a>\n\n## 智能合约安全参考书目\n\n很多包含代码，示例和见解的文档已经由社区编写完成。这里是其中的一些，你可以随意添加更多新的内容。\n\n##### 来自以太坊核心开发人员\n\n- [How to Write Safe Smart Contracts](https://chriseth.github.io/notes/talks/safe_solidity) (Christian Reitwiessner)\n- [Smart Contract Security](https://blog.ethereum.org/2016/06/10/smart-contract-security/) (Christian Reitwiessner)\n- [Thinking about Smart Contract Security](https://blog.ethereum.org/2016/06/19/thinking-smart-contract-security/) (Vitalik Buterin)\n- [Solidity](http://solidity.readthedocs.io)\n- [Solidity Security Considerations](http://solidity.readthedocs.io/en/latest/security-considerations.html)\n\n##### 来自社区\n\n- http://forum.ethereum.org/discussion/1317/reentrant-contracts\n- http://hackingdistributed.com/2016/06/16/scanning-live-ethereum-contracts-for-bugs/\n- http://hackingdistributed.com/2016/06/18/analysis-of-the-dao-exploit/\n- http://hackingdistributed.com/2016/06/22/smart-contract-escape-hatches/\n- http://martin.swende.se/blog/Devcon1-and-contract-security.html\n- http://publications.lib.chalmers.se/records/fulltext/234939/234939.pdf\n- http://vessenes.com/deconstructing-thedao-attack-a-brief-code-tour\n- http://vessenes.com/ethereum-griefing-wallets-send-w-throw-considered-harmful\n- http://vessenes.com/more-ethereum-attacks-race-to-empty-is-the-real-deal\n- https://blog.blockstack.org/simple-contracts-are-better-contracts-what-we-can-learn-from-the-dao-6293214bad3a\n- https://blog.slock.it/deja-vu-dao-smart-contracts-audit-results-d26bc088e32e\n- https://blog.vdice.io/wp-content/uploads/2016/11/vsliceaudit_v1.3.pdf\n- https://eprint.iacr.org/2016/1007.pdf\n- https://github.com/Bunjin/Rouleth/blob/master/Security.md\n- https://github.com/LeastAuthority/ethereum-analyses\n- https://medium.com/@ConsenSys/assert-guards-towards-automated-code-bounties-safe-smart-contract-coding-on-ethereum-8e74364b795c\n- https://medium.com/@coriacetic/in-bits-we-trust-4e464b418f0b\n- https://medium.com/@hrishiolickel/why-smart-contracts-fail-undiscovered-bugs-and-what-we-can-do-about-them-119aa2843007\n- https://medium.com/@peterborah/we-need-fault-tolerant-smart-contracts-ec1b56596dbc\n- https://medium.com/zeppelin-blog/zeppelin-framework-proposal-and-development-roadmap-fdfa9a3a32ab\n- https://pdaian.com/blog/chasing-the-dao-attackers-wake\n- http://www.comp.nus.edu.sg/~loiluu/papers/oyente.pdf\n\n## Reviewers\n\n## The following people have reviewed this document (date and commit they reviewed in parentheses): Bill Gleim (07/29/2016 3495fb5) Bill Gleim (03/15/2017 0244f4e)\n\n## License\n\nLicensed under [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0)\n\nLicensed under [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)\n"
  },
  {
    "path": "README.md",
    "content": "[<img width=\"200\" alt=\"get in touch with Consensys Diligence\" src=\"https://user-images.githubusercontent.com/2865694/56826101-91dcf380-685b-11e9-937c-af49c2510aa0.png\">](https://consensys.net/diligence/)<br/>\n<sup>\n[[  🌐  ](https://consensys.net/diligence/)  [  📩  ](mailto:diligence@consensys.net)  [  🔥  ](https://consensys.net/diligence/tools/)]\n</sup><br/><br/>\n\n\n# Smart Contract Security Best Practices\n\nVisit the documentation site: https://consensysdiligence.github.io/smart-contract-best-practices/\n\nRead the docs in Chinese: https://github.com/ConsenSysDiligence/smart-contract-best-practices/blob/master/README-zh.md\nRead the docs in Vietnamese: https://github.com/ConsenSysDiligence/smart-contract-best-practices/blob/master/README-vi.md\n\n## Contributions are welcome!\n\nFeel free to submit a pull request, with anything from small fixes, to full new sections. If you are writing new content, please reference the [contributing](./docs/about/index.md) page for guidance on style.\n\nSee the [issues](https://github.com/ConsenSysDiligence/smart-contract-best-practices/issues) for topics that need to be covered or updated. If you have an idea you'd like to discuss, please chat with us in [Gitter](https://gitter.im/ConsenSys/smart-contract-best-practices).\n\n## Building the documentation site\n\n```\ngit clone git@github.com:ConsenSys/smart-contract-best-practices.git\ncd smart-contract-best-practices\npip install -r requirements.txt\nmkdocs build \n```\n\nTo run the server (and restart on failure):\n\n```\nuntil mkdocs serve; do :; done\n```\n\nYou can also use the `mkdocs serve` command to view the site on localhost, and live reload whenever you save changes.\n\n## Redeploying the documentation site\n\n```\nmkdocs gh-deploy\n```\n"
  },
  {
    "path": "custom/.icons/fontawesome/LICENSE.txt",
    "content": "Font Awesome Free License\n-------------------------\n\nFont Awesome Free is free, open source, and GPL friendly. You can use it for\ncommercial projects, open source projects, or really almost whatever you want.\nFull Font Awesome Free license: https://fontawesome.com/license/free.\n\n# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/)\nIn the Font Awesome Free download, the CC BY 4.0 license applies to all icons\npackaged as SVG and JS file types.\n\n# Fonts: SIL OFL 1.1 License (https://scripts.sil.org/OFL)\nIn the Font Awesome Free download, the SIL OFL license applies to all icons\npackaged as web and desktop font files.\n\n# Code: MIT License (https://opensource.org/licenses/MIT)\nIn the Font Awesome Free download, the MIT license applies to all non-font and\nnon-icon files.\n\n# Attribution\nAttribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font\nAwesome Free files already contain embedded comments with sufficient\nattribution, so you shouldn't need to do anything additional when using these\nfiles normally.\n\nWe've kept attribution comments terse, so we ask that you do not actively work\nto remove them from files, especially code. They're a great way for folks to\nlearn about Font Awesome.\n\n# Brand Icons\nAll brand icons are trademarks of their respective owners. The use of these\ntrademarks does not indicate endorsement of the trademark holder by Font\nAwesome, nor vice versa. **Please do not use brand logos for any purpose except\nto represent the company, product, or service to which they refer.**\n"
  },
  {
    "path": "custom/.icons/octicons/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2020 GitHub Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "custom/main.html",
    "content": "{% extends \"base.html\" %}\n\n{% block scripts %}\n  {{ super() }}\n  \n<!-- Google Tag Manager (noscript) -->\n<noscript><iframe src=\"https://www.googletagmanager.com/ns.html?id=GTM-MCQTD6XJ\"\n    height=\"0\" width=\"0\" style=\"display:none;visibility:hidden\"></iframe></noscript>\n    <!-- End Google Tag Manager (noscript) -->\n{% endblock %}"
  },
  {
    "path": "custom/partials/integrations/analytics/custom.html",
    "content": "<!-- Google Tag Manager -->\n<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':\n    new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],\n    j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=\n    'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);\n    })(window,document,'script','dataLayer','GTM-MCQTD6XJ');</script>\n    <!-- End Google Tag Manager -->"
  },
  {
    "path": "docs/about/index.md",
    "content": "{! CONTRIBUTING.md !}\n"
  },
  {
    "path": "docs/about/license.md",
    "content": "Copyright 2016 Smart Contract Best Practices Authors\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in\ncompliance with the License. You may obtain a copy of the License at\n\n```\nhttp://www.apache.org/licenses/LICENSE-2.0\n```\n\nUnless required by applicable law or agreed to in writing, software distributed under the License\nis distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied. See the License for the specific language governing permissions and limitations under the\nLicense.\n"
  },
  {
    "path": "docs/attacks/denial-of-service.md",
    "content": "## DoS with (Unexpected) revert\n\nConsider a simple auction contract:\n\n```sol\n// INSECURE\ncontract Auction {\n    address currentLeader;\n    uint highestBid;\n\n    function bid() payable {\n        require(msg.value > highestBid);\n\n        require(currentLeader.send(highestBid)); // Refund the old leader, if it fails then revert\n\n        currentLeader = msg.sender;\n        highestBid = msg.value;\n    }\n}\n```\n\nIf attacker bids using a smart contract which has a fallback function that reverts any payment, the\nattacker can win any auction. When it tries to refund the old leader, it reverts if the refund\nfails. This means that a malicious bidder can become the leader while making sure that any refunds\nto their address will *always* fail. In this way, they can prevent anyone else from calling the\n`bid()` function, and stay the leader forever. A recommendation is to set up a\n[pull payment system](../development-recommendations/general/external-calls.md) instead, as\ndescribed earlier.\n\nAnother example is when a contract may iterate through an array to pay users (e.g., supporters in a\ncrowdfunding contract). It's common to want to make sure that each payment succeeds. If not, one\nshould revert. The issue is that if one call fails, you are reverting the whole payout system,\nmeaning the loop will never complete. No one gets paid because one address is forcing an error.\n\n```sol\naddress[] private refundAddresses;\nmapping (address => uint) public refunds;\n\n// bad\nfunction refundAll() public {\n    for(uint x; x < refundAddresses.length; x++) { // arbitrary length iteration based on how many addresses participated\n        require(refundAddresses[x].send(refunds[refundAddresses[x]])) // doubly bad, now a single failure on send will hold up all funds\n    }\n}\n```\n\nAgain, the recommended solution is to\n[favor pull over push payments](../development-recommendations/general/external-calls.md).\n\nSee [SWC-113](https://swcregistry.io/docs/SWC-113)\n\n\n## DoS with Block Gas Limit\n\nEach block has an upper bound on the amount of gas that can be spent, and thus the amount\ncomputation that can be done. This is the Block Gas Limit. If the gas spent exceeds this limit, the\ntransaction will fail. This leads to a couple of possible Denial of Service vectors:\n\n### Gas Limit DoS on a Contract via Unbounded Operations\n\nYou may have noticed another problem with the previous example: by paying out to everyone at once,\nyou risk running into the block gas limit.\n\nThis can lead to problems even in the absence of an intentional attack. However, it's especially\nbad if an attacker can manipulate the amount of gas needed. In the case of the previous example,\nthe attacker could add a bunch of addresses, each of which needs to get a very small refund. The\ngas cost of refunding each of the attacker's addresses could, therefore, end up being more than the\ngas limit, blocking the refund transaction from happening at all.\n\nThis is another reason to\n[favor pull over push payments](../development-recommendations/general/external-calls.md).\n\nIf you absolutely must loop over an array of unknown size, then you should plan for it to\npotentially take multiple blocks, and therefore require multiple transactions. You will need to\nkeep track of how far you've gone, and be able to resume from that point, as in the following\nexample:\n\n```sol\nstruct Payee {\n    address addr;\n    uint256 value;\n}\n\nPayee[] payees;\nuint256 nextPayeeIndex;\n\nfunction payOut() {\n    uint256 i = nextPayeeIndex;\n    while (i < payees.length && gasleft() > 200000) {\n      payees[i].addr.send(payees[i].value);\n      i++;\n    }\n    nextPayeeIndex = i;\n}\n```\n\nYou will need to make sure that nothing bad will happen if other transactions are processed while\nwaiting for the next iteration of the `payOut()` function. So only use this pattern if absolutely\nnecessary.\n\n### Gas Limit DoS on the Network via Block Stuffing\n\nEven if your contract does not contain an unbounded loop, an attacker can prevent other\ntransactions from being included in the blockchain for several blocks by placing computationally\nintensive transactions with a high enough gas price.\n\nTo do this, the attacker can issue several transactions which will consume the entire gas limit,\nwith a high enough gas price to be included as soon as the next block is mined. No gas price can\nguarantee inclusion in the block, but the higher the price is, the higher is the chance.\n\nIf the attack succeeds, no other transactions will be included in the block. Sometimes, an\nattacker's goal is to block transactions to a specific contract prior to specific time.\n\nThis attack [was conducted](https://solmaz.io/2018/10/18/anatomy-block-stuffing/) on Fomo3D, a\ngambling app. The app was designed to reward the last address that purchased a \"key\". Each key\npurchase extended the timer, and the game ended once the timer went to 0. The attacker bought a key\nand then stuffed 13 blocks in a row until the timer was triggered and the payout was released.\nTransactions sent by attacker took 7.9 million gas on each block, so the gas limit allowed a few\nsmall \"send\" transactions (which take 21,000 gas each), but disallowed any calls to the `buyKey()`\nfunction (which costs 300,000+ gas).\n\nA Block Stuffing attack can be used on any contract requiring an action within a certain time\nperiod. However, as with any attack, it is only profitable when the expected reward exceeds its\ncost. The cost of this attack is directly proportional to the number of blocks which need to be\nstuffed. If a large payout can be obtained by preventing actions from other participants, your\ncontract will likely be targeted by such an attack.\n\nSee [SWC-128](https://swcregistry.io/docs/SWC-128)\n\n"
  },
  {
    "path": "docs/attacks/deprecated.md",
    "content": "\nThese are attacks which are no longer possible due to changes in the protocol or improvements to\nsolidity. They are recorded here for posterity and awareness.\n\n### Call Depth Attack (deprecated)\n\nAs of the [EIP 150](https://github.com/ethereum/EIPs/issues/150) hardfork, call depth attacks are\nno longer\nrelevant<sup><a href='http://ethereum.stackexchange.com/questions/9398/how-does-eip-150-change-the-call-depth-attack'>\\*</a></sup>\n(all gas would be consumed well before reaching the 1024 call depth limit).\n\n### Constantinople Reentrancy Attack\n\nOn January 16th, 2019, Constantinople protocol upgrade was delayed due to a security vulnerability\nenabled by [EIP 1283](https://eips.ethereum.org/EIPS/eip-1283). _EIP 1283: Net gas metering for\nSSTORE without dirty maps_ proposes changes to reduce excessive gas costs on dirty storage writes.\n\nThis change led to possibility of a new reentrancy vector making previously known secure withdrawal\npatterns (`.send()` and `.transfer()`) unsafe in specific\nsituations<sup><a href='https://medium.com/chainsecurity/constantinople-enables-new-reentrancy-attack-ace4088297d9'>\\*</a></sup>,\nwhere the attacker could hijack the control flow and use the remaining gas enabled by EIP 1283,\nleading to vulnerabilities due to reentrancy.\n"
  },
  {
    "path": "docs/attacks/force-feeding.md",
    "content": "!!! tip\n\n    Thank you for visiting the Smart Contract Security Best Practices. Please note that this resource is no longer actively maintained. Instead, we recommend visiting the [Smart Contract Security Field Guide](https://scsfg.io/). The Field Guide is regularly updated and curated by the same security engineer who previously contributed to the Best Practices guide.\n\n    The resource on unexpected Ether transfers can be found here: https://scsfg.io/hackers/unexpected-ether/\n\n\nForcing a smart contract to hold an Ether balance can influence its internal accounting and security assumptions.\nThere are multiple ways a smart contract can receive Ether. The hierarchy is as follows:\n\n1. Check whether a payable external `receive` function is defined.\n2. If not, check whether a payable external `fallback` function is defined.\n3. Revert.\n\nThe precedence of each function is explained in this great graphic from the [Solidity by Example](https://solidity-by-example.org/sending-ether/) article:\n\n```\nWhich function is called, fallback() or receive()?\n\n           send Ether\n               |\n         msg.data is empty?\n              / \\\n            yes  no\n            /     \\\nreceive() exists?  fallback()\n         /   \\\n        yes   no\n        /      \\\n    receive()   fallback()\n```\n\nConsider the following example:\n\n```sol\npragma solidity ^0.8.13;\n\ncontract Vulnerable {\n    receive() external payable {\n        revert();\n    }\n\n    function somethingBad() external {\n        require(address(this).balance > 0);\n        // Do something bad\n    }\n}\n```\n\nThe contract's logic seemingly disallows direct payments and prevents \"something bad\" from happening.\nHowever, calling `revert` in both `fallback` and `receive` **cannot prevent the contract from receiving Ether**.\nThe following techniques can be used to force-feed Ether to a smart contract.\n\n### Selfdestruct\n\nWhen the `SELFDESTRUCT` opcode is called, funds of the calling address are sent to the address on the stack, and execution is immediately halted.\nSince this opcode works on the EVM-level, Solidity-level functions that might block the receipt of Ether [will not be executed](https://solidity.readthedocs.io/en/develop/security-considerations.html#sending-and-receiving-ether).\n\n\n### Pre-calculated Deployments\n\nAdditionally, the target address of newly deployed smart contracts is generated in a deterministic fashion.\nThe address generation can be looked up in any EVM implementation, such as the [py-evm reference implementation](https://github.com/ethereum/py-evm/blob/e924f63992a35212616b4e20355d161bc4348925/eth/_utils/address.py#L17-L18) by the Ethereum Foundation:\n\n```python\ndef generate_contract_address(address: Address, nonce: int) -> Address:\n    return force_bytes_to_address(keccak(rlp.encode([address, nonce])))\n```\n\nAn attacker can send funds to this address before the deployment has happened.\nThis is also illustrated by [this 2017 Underhanded Solidity Contest submission](https://github.com/Arachnid/uscc/tree/master/submissions-2017/ricmoo).\n\n\n### Block Rewards and Coinbase\n\nDepending on the attacker's capabilities, they can also start proof-of-work mining.\nBy setting the target address to their `coinbase`, block rewards will be added to its balance.\nAs this is yet another EVM-level capability, checks performed by Solidity are ineffective.\n\n\n### Solution\n\nThe above effects illustrate that relying on exact comparisons to the contract's Ether balance is unreliable.\nThe smart contract's business logic must consider that the actual balance associated with it can be higher than the internal accounting's value.\n\n**In general, we strongly advise against using the contract's balance as a guard.**\n\nMore information can be found in [SWC-132](https://swcregistry.io/docs/SWC-132)."
  },
  {
    "path": "docs/attacks/frontrunning.md",
    "content": "!!! tip\n\n    Thank you for visiting the Smart Contract Security Best Practices. Please note that this resource is no longer actively maintained. Instead, we recommend visiting the [Smart Contract Security Field Guide](https://scsfg.io/). The Field Guide is regularly updated and curated by the same security engineer who previously contributed to the Best Practices guide.\n    \n    The resource on frontrunning attacks can be found here: https://scsfg.io/hackers/frontrunning/\n\nSince all transactions are visible in the mempool for a short while before being executed,\nobservers of the network can see and react to an action before it is included in a block. An\nexample of how this can be exploited is with a decentralized exchange where a buy order transaction\ncan be seen, and second order can be broadcast and executed before the first transaction is\nincluded. Protecting against this is difficult, as it would come down to the specific contract\nitself.\n\nFront-running, coined originally for traditional financial markets, is the race to order the chaos\nto the winner's benefit. In financial markets, the flow of information gave birth to intermediaries\nthat could simply profit by being the first to know and react to some information. These attacks\nmostly had been within stock market deals and early domain registries, such as whois gateways.\n\n!!! cite \"front-run·ning (/ˌfrəntˈrəniNG/)\"\n    *noun*: front-running;\n\n    1. *STOCK MARKET*\n\n        > the practice by market makers of dealing on advance information provided by their brokers and investment analysts, before their clients have been given the information.\n        <!-- [[OXFORD](https://www.lexico.com/en/definition/front-running)] -->\n\n### Taxonomy\n\nBy defining a [taxonomy](https://arxiv.org/abs/1902.05164) and differentiating each group from\nanother, we can make it easier to discuss the problem and find solutions for each group.\n\nWe define the following categories of front-running attacks:\n\n1. Displacement\n1. Insertion\n1. Suppression\n\n#### Displacement\n\nIn the first type of attack, *a displacement attack*, it is **not important** for Alice’s (User)\nfunction call to run after Mallory (Adversary) runs her function. Alice’s can be orphaned or run\nwith no meaningful effect. Examples of displacement include:\n\n- Alice trying to register a domain name and Mallory registering it first;\n- Alice trying to submit a bug to receive a bounty and Mallory stealing it and submitting it first;\n- Alice trying to submit a bid in an auction and Mallory copying it.\n\nThis attack is commonly performed by increasing the `gasPrice` higher than network average, often\nby a multiplier of 10 or more.\n\n#### Insertion\n\nFor this type of attack, it is **important** to the adversary that the original function call runs\nafter her transaction. In an insertion attack, after Mallory runs her function, the state of the\ncontract is changed and she needs Alice’s original function to run on this modified state. For\nexample, if Alice places a purchase order on a blockchain asset at a higher price than the best\noffer, Mallory will insert two transactions: she will purchase at the best offer price and then\noffer the same asset for sale at Alice’s slightly higher purchase price. If Alice’s transaction is\nthen run after, Mallory will profit on the price difference without having to hold the asset.\n\nAs with displacement attacks, this is usually done by outbidding Alice's transaction in the gas\nprice auction.\n\n!!! info \"Transaction Order Dependence\"\n    Transaction Order Dependence is equivalent to race\n    condition in smart contracts. An example, if one function sets the reward percentage, and the\n    withdraw function uses that percentage; then withdraw transaction can be front-run by a change\n    reward function call, which impacts the amount that will be withdrawn eventually.\n\n    See [SWC-114](https://swcregistry.io/docs/SWC-114)\n\n<!-- Based on Geth default ordering, it's easy to sandwich a transaction by sending two transactions each with 1 wei higher or lower. -->\n\n<!-- Cite theo/daniel's talk -->\n\n#### Suppression\n\nIn a suppression attack, a.k.a *Block Stuffing* attacks, after Mallory runs her function, she tries\nto delay Alice from running her function.\n\nThis was the case with the first winner of the \"Fomo3d\" game and some other on-chain hacks. The\nattacker sent multiple transactions with a high `gasPrice` and `gasLimit` to custom smart contracts\nthat assert (or use other means) to consume all the gas and fill up the block's `gasLimit`.\n\n!!! note \"Variants\"\n    Each of these attacks has two variants, *asymmetric* and *bulk*.\n\n    In some cases, Alice and Mallory are performing different operations. For example, Alice is trying to cancel an offer, and Mallory is trying to fulfill it first. We call this *asymmetric displacement*. In other cases, Mallory is trying to run a large set of functions: for example, Alice and others are trying to buy a limited set of shares offered by a firm on a blockchain. We call this *bulk displacement*.\n\n\n### Mitigations\n\nFront-running is a pervasive issue on public blockchains such as Ethereum.\n\nThe best remediation is to **remove the benefit of front-running in your application**, mainly by\nremoving the importance of transaction ordering or time. For example, in markets, it would be\nbetter to implement batch auctions (this also protects against high-frequency trading concerns).\nAnother way is to use a pre-commit scheme (“I’m going to submit the details later”). A third option\nis to mitigate the cost of front-running by specifying a maximum or minimum acceptable price range\non a trade, thereby limiting price slippage.\n\n**Transaction Ordering:** Go-Ethereum (Geth) nodes, order the transactions based on their\n`gasPrice` and address nonce. This, however, results in a gas auction between participants in the\nnetwork to get included in the block currently being mined.\n\n**Confidentiality:** Another approach is to limit the visibility of the transactions, this can be\ndone using a \"commit and reveal\" scheme.\n\n<!-- cite and properly define commit and reveal -->\n\nA simple implementation is to store the keccak256 hash of the data in the first transaction, then\nreveal the data and verify it against the hash in the second transaction. However note that the\ntransaction itself leaks the intention and possibly the value of the collateralization. There are\nenhanced commit and reveal schemes that are more secure, however require more transactions to\nfunction, e.g. [submarine sends](https://libsubmarine.org/).\n\n"
  },
  {
    "path": "docs/attacks/griefing.md",
    "content": "!!! tip\n\n    Thank you for visiting the Smart Contract Security Best Practices. Please note that this resource is no longer actively maintained. Instead, we recommend visiting the [Smart Contract Security Field Guide](https://scsfg.io/). The Field Guide is regularly updated and curated by the same security engineer who previously contributed to the Best Practices guide.\n\n    The resource on griefing attacks can be found here: https://scsfg.io/hackers/griefing/\n\nThis attack may be possible on a contract which accepts generic data and uses it to make a call\nanother contract (a 'sub-call') via the low level `address.call()` function, as is often the case\nwith multisignature and transaction relayer contracts.\n\nIf the call fails, the contract has two options:\n\n1. revert the whole transaction\n1. continue execution.\n\nTake the following example of a simplified `Relayer` contract which continues execution regardless\nof the outcome of the subcall:\n\n```sol\ncontract Relayer {\n    mapping (bytes => bool) executed;\n\n    function relay(bytes _data) public {\n        // replay protection; do not call the same transaction twice\n        require(executed[_data] == 0, \"Duplicate call\");\n        executed[_data] = true;\n        innerContract.call(bytes4(keccak256(\"execute(bytes)\")), _data);\n    }\n}\n```\n\nThis contract allows transaction relaying. Someone who wants to make a transaction but can't\nexecute it by himself (e.g. due to the lack of ether to pay for gas) can sign data that he wants to\npass and transfer the data with his signature over any medium. A third party \"forwarder\" can then\nsubmit this transaction to the network on behalf of the user.\n\nIf given just the right amount of gas, the `Relayer` would complete execution recording the\n`_data`argument in the `executed` mapping, but the subcall would fail because it received\ninsufficient gas to complete execution.\n\n!!! Note\n    When a contract makes a sub-call to another contract, the EVM limits the gas forwarded to\n    [to 63/64 of the remaining gas](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-150.md),\n\nAn attacker can use this to censor transactions, causing them to fail by sending them with a low\namount of gas. This attack is a form of \"[griefing](https://en.wikipedia.org/wiki/Griefer)\": It\ndoesn't directly benefit the attacker, but causes grief for the victim. A dedicated attacker,\nwilling to consistently spend a small amount of gas could theoretically censor all transactions\nthis way, if they were the first to submit them to `Relayer`.\n\nOne way to address this is to implement logic requiring forwarders to provide enough gas to finish\nthe subcall. If the miner tried to conduct the attack in this scenario, the `require` statement\nwould fail and the inner call would revert. A user can specify a minimum gasLimit along with the\nother data (in this example, typically the `_gasLimit` value would be verified by a signature, but\nthat is omitted for simplicity in this case).\n\n```sol\n// contract called by Relayer\ncontract Executor {\n    function execute(bytes _data, uint _gasLimit) {\n        require(gasleft() >= _gasLimit);\n        ...\n    }\n}\n```\n\nAnother solution is to permit only trusted accounts to relay the transaction.\n\n"
  },
  {
    "path": "docs/attacks/index.md",
    "content": "!!! tip\n\n    Seeking more detailed information on smart contract attacks? The [Smart Contract Security Field Guide](https://scsfg.io/hackers/) offers an extensive range of attack strategies with in-depth explanations on vulnerabilities, including new code samples for a hands-on learning experience. Enhance your understanding and stay ahead of potential threats by visiting this continuously updated resource.\n\nThe following is a list of known attacks which you should be aware of, and defend against when\nwriting smart contracts.\n\n| Category                                          | Description                                                                                                          |\n| ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |\n| [Reentrancy](./reentrancy.md)                     | Intra- and inter-function reentrancy attacks and potentially faulty solutions to them.                               |\n| [Oracle Manipulation](./oracle-manipulation.md)   | Manipulation of external data providers and potential solutions to oracle security issues.                           |\n| [Frontrunning](./frontrunning.md)                 | A definition and taxonomy around frontrunning and related attacks.                                                   |\n| [Timestamp Dependence](./timestamp-dependence.md) | Attacks relating to the timing of a transaction.                                                                     |\n| [Insecure Arithmetic](./insecure-arithmetic.md)   | Integer overflows and underflows.                                                                                    |\n| [Denial of Service](./denial-of-service.md)       | Denial of service attacks through unexpected reverts and the block gas limit.                                        |\n| [Griefing](./griefing.md)                         | Attacks relating to bad faith players around a smart contract system.                                                |\n| [Force Feeding](./force-feeding.md)               | Forcing Ether to be sent to smart contracts to manipulate balance checks.                                            |\n| [Deprecated/Historical](./deprecated.md)          | Attacks that are part of Ethereum's history and vulnerabilities that have been fixes on a (Solidity) compiler level. |\n| [More](./more.md)                                 | Where to find more information about vulnerabilities and weaknesses.                                                 |\n"
  },
  {
    "path": "docs/attacks/insecure-arithmetic.md",
    "content": "\nConsider a simple token transfer:\n\n```sol\nmapping (address => uint256) public balanceOf;\n\n// INSECURE\nfunction transfer(address _to, uint256 _value) {\n    /* Check if sender has balance */\n    require(balanceOf[msg.sender] >= _value);\n    /* Add and subtract new balances */\n    balanceOf[msg.sender] -= _value;\n    balanceOf[_to] += _value;\n}\n\n// SECURE\nfunction transfer(address _to, uint256 _value) {\n    /* Check if sender has balance and for overflows */\n    require(balanceOf[msg.sender] >= _value && balanceOf[_to] + _value >= balanceOf[_to]);\n\n    /* Add and subtract new balances */\n    balanceOf[msg.sender] -= _value;\n    balanceOf[_to] += _value;\n}\n```\n\nIf a balance reaches the *maximum uint value (2^256)* it will circle back to zero which checks for\nthe condition. This may or may not be relevant, depending on the implementation. Think about\nwhether or not the `uint` value has an opportunity to approach such a large number. Think about how\nthe `uint` variable changes state, and who has authority to make such changes. If any user can call\nfunctions which update the `uint` value, it's more vulnerable to attack. If only an admin has\naccess to change the variable's state, you might be safe. If a user can increment by only 1 at a\ntime, you are probably also safe because there is no feasible way to reach this limit.\n\nThe same is true for underflow. If a uint is made to be less than zero, it will cause an underflow\nand get set to its maximum value.\n\nBe careful with the smaller data-types like uint8, uint16, uint24...etc: they can even more easily\nhit their maximum value.\n\n!!! Warning\n    Be aware there are around [20 cases for overflow and underflow](https://github.com/ethereum/solidity/issues/796#issuecomment-253578925).\n\n    One simple solution to mitigate the common mistakes for overflow and underflow is to use\n    `SafeMath.sol`\n    [library](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/ae54e6de1d77c60881e4c85ffbdb7f9d76b71efe/contracts/utils/math/SafeMath.sol)\n    for arithmetic functions. Solidity automatically reverts on integer overflow and underflow, as of\n    version 0.8.0.\n\n    See [SWC-101](https://swcregistry.io/docs/SWC-101)\n"
  },
  {
    "path": "docs/attacks/more.md",
    "content": "The [Smart Contract Weakness Classification Registry](https://smartcontractsecurity.github.io/SWC-registry/)\noffers a complete and up-to-date catalogue of known smart contract vulnerabilities and\nanti-patterns along with real-world examples. Browsing the registry is a good way of keeping\nup-to-date with the latest attacks. It has been proposed formally in [EIP-1470](https://github.com/ethereum/EIPs/issues/1469) and is loosely aligned with the Common Weakness Enumeration ([CWE](https://cwe.mitre.org/)).\n\nAdditionally, the [Smart Contract Security Verification Standard (SCSVS)](https://github.com/securing/SCSVS) contains a checklist-style collection of vital security properties aimed at standardizing the security of smart contracts for developers, architects, security reviewers and vendors.\n"
  },
  {
    "path": "docs/attacks/oracle-manipulation.md",
    "content": "!!! tip\n\n    Thank you for visiting the Smart Contract Security Best Practices. Please note that this resource is no longer actively maintained. Instead, we recommend visiting the [Smart Contract Security Field Guide](https://scsfg.io/). The Field Guide is regularly updated and curated by the same security engineer who previously contributed to the Best Practices guide.\n\n    The resource on oracle manipulation attacks can be found here: https://scsfg.io/hackers/oracle-manipulation/\n\n\nProtocols that rely on external data as inputs (from what's known as an\n[oracle](https://medium.com/better-programming/what-is-a-blockchain-oracle-f5ccab8dbd72?source=friends_link&sk=d921a38466df8a9176ed8dd767d8c77d))\nautomatically execute even if the data is incorrect, due to the nature of smart contracts. If a\nprotocol relies on an oracle that is hacked, deprecated, or has malicious intent, all processes\nthat depend on the oracle can now operate with disastrous effects.\n\nFor example:\n\n1. Protocol gets price from single Uniswap pool\n1. Malicious actor drains one side of the pool with a large transaction\n1. Uniswap pool starts responding with a price more than 100x what it should be\n1. Protocol operates as if that were the actual price, giving the manipulator a better price\n\nWe've seen examples where this will liquidate positions, allow insane arbitrage, ruin DEX\npositions, and more.\n\n### Oracle Manipulation Solutions\n\nThe easiest way to solve this is to use decentralized oracles such as:\n\n* [Chainlink](https://chain.link/) is the leading decentralized oracle provider, and the Chainlink network can be leveraged to bring decentralized data on-chain.\n* [Tellor](https://tellor.io/) is an oracle that provides censorship resistant data, secured by crypto-economic incentives, that ensure data can be provided by anyone, anytime, and checked by everyone.\n* [Witnet](https://witnet.io/) leverages state-of-the-art cryptographic and economic techniques to provide your smart contracts with secure data input.\n\nUsing a median of multiple oracles provides heighten security since it is harder and more expensive to attack multiple oracles than one and it ensures that your smart contract gets the data it needs even if one oracle or API call fails. \n\nAnother common solution is to use a time-weighted average price feed, so that price is averaged out\nover `X` time periods and multiple sources. Not only does this prevent oracle manipulation, but it also reduces the\nchance you can be front-run, as an order executed right before yours won't have as drastic an\nimpact on price. However, always keep in mind that low liquidity assets are generally easier/cheaper to manipulate, even for a period of time. One tool that gathers Uniswap price feeds every thirty minutes is\n[Keep3r](https://docs.uniquote.finance/). If you're looking to build a custom solution,\n[Uniswap provides a sliding window example](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/examples/ExampleSlidingWindowOracle.sol).\n"
  },
  {
    "path": "docs/attacks/reentrancy.md",
    "content": "!!! tip\n\n    Thank you for visiting the Smart Contract Security Best Practices. Please note that this resource is no longer actively maintained. Instead, we recommend visiting the [Smart Contract Security Field Guide](https://scsfg.io/). The Field Guide is regularly updated and curated by the same security engineer who previously contributed to the Best Practices guide.\n\n    The resource on reentrancy can be found here: https://scsfg.io/hackers/reentrancy/\n\n\nOne of the major dangers of [calling external contracts](../development-recommendations/general/external-calls.md) is that\nthey can take over the control flow, and make changes to your data that the calling function wasn't\nexpecting. This class of bugs can take many forms, and both of the major bugs that led to the DAO's\ncollapse were bugs of this sort.\n\n### Reentrancy on a Single Function\n\nThe first version of this bug to be noticed involved functions that could be called repeatedly,\nbefore the first invocation of the function was finished. This may cause the different invocations\nof the function to interact in destructive ways.\n\n```sol\n// INSECURE\nmapping (address => uint) private userBalances;\n\nfunction withdrawBalance() public {\n    uint amountToWithdraw = userBalances[msg.sender];\n    (bool success, ) = msg.sender.call.value(amountToWithdraw)(\"\"); // At this point, the caller's code is executed, and can call withdrawBalance again\n    require(success);\n    userBalances[msg.sender] = 0;\n}\n```\n\nSince the user's balance is not set to 0 until the very end of the function, the second (and later)\ninvocations will still succeed and will withdraw the balance over and over again.\n\n!!! Factoid\n    A DAO is a Decentralized Autonomous Organization. Its goal is to codify the rules and\n    decision-making apparatus of an organization, eliminating the need for documents and people in\n    governing, creating a structure with decentralized control.\n\n```\nOn June 17th 2016, [The DAO](https://www.coindesk.com/understanding-dao-hack-journalists) was hacked and 3.6 million Ether ($50 Million) were stolen using the first reentrancy attack.\n\nEthereum Foundation issued a critical update to rollback the hack. This resulted in Ethereum being forked into Ethereum Classic and Ethereum.\n```\n\nIn the example given, the best way to prevent this attack is to make sure you don't call an\nexternal function until you've done all the internal work you need to do:\n\n```sol\nmapping (address => uint) private userBalances;\n\nfunction withdrawBalance() public {\n    uint amountToWithdraw = userBalances[msg.sender];\n    userBalances[msg.sender] = 0;\n    (bool success, ) = msg.sender.call.value(amountToWithdraw)(\"\"); // The user's balance is already 0, so future invocations won't withdraw anything\n    require(success);\n}\n```\n\nNote that if you had another function which called `withdrawBalance()`, it would be potentially\nsubject to the same attack, so you must treat any function which calls an untrusted contract as\nitself untrusted. See below for further discussion of potential solutions.\n\n### Cross-function Reentrancy\n\nAn attacker may also be able to do a similar attack using two different functions that share the\nsame state.\n\n```sol\n// INSECURE\nmapping (address => uint) private userBalances;\n\nfunction transfer(address to, uint amount) {\n    if (userBalances[msg.sender] >= amount) {\n       userBalances[to] += amount;\n       userBalances[msg.sender] -= amount;\n    }\n}\n\nfunction withdrawBalance() public {\n    uint amountToWithdraw = userBalances[msg.sender];\n    (bool success, ) = msg.sender.call.value(amountToWithdraw)(\"\"); // At this point, the caller's code is executed, and can call transfer()\n    require(success);\n    userBalances[msg.sender] = 0;\n}\n```\n\nIn this case, the attacker calls `transfer()` when their code is executed on the external call in\n`withdrawBalance`. Since their balance has not yet been set to 0, they are able to transfer the\ntokens even though they already received the withdrawal. This vulnerability was also used in the\nDAO attack.\n\nThe same solutions will work, with the same caveats. Also note that in this example, both functions\nwere part of the same contract. However, the same bug can occur across multiple contracts, if those\ncontracts share state.\n\n### Pitfalls in Reentrancy Solutions\n\nSince reentrancy can occur across multiple functions, and even multiple contracts, any solution\naimed at preventing reentrancy with a single function will not be sufficient.\n\nInstead, **we have recommended finishing all internal work (ie. state changes) first, and only then\ncalling the external function**. This rule, if followed carefully, will allow you to avoid\nvulnerabilities due to reentrancy. However, you need to not only avoid calling external functions\ntoo soon, but also avoid calling functions which call external functions. For example, the\nfollowing is insecure:\n\n```sol\n// INSECURE\nmapping (address => uint) private userBalances;\nmapping (address => bool) private claimedBonus;\nmapping (address => uint) private rewardsForA;\n\nfunction withdrawReward(address recipient) public {\n    uint amountToWithdraw = rewardsForA[recipient];\n    rewardsForA[recipient] = 0;\n    (bool success, ) = recipient.call.value(amountToWithdraw)(\"\");\n    require(success);\n}\n\nfunction getFirstWithdrawalBonus(address recipient) public {\n    require(!claimedBonus[recipient]); // Each recipient should only be able to claim the bonus once\n\n    rewardsForA[recipient] += 100;\n    withdrawReward(recipient); // At this point, the caller will be able to execute getFirstWithdrawalBonus again.\n    claimedBonus[recipient] = true;\n}\n```\n\nEven though `getFirstWithdrawalBonus()` doesn't directly call an external contract, the call in\n`withdrawReward()` is enough to make it vulnerable to a reentrancy. You therefore need to treat\n`withdrawReward()` as if it were also untrusted.\n\n```sol\nmapping (address => uint) private userBalances;\nmapping (address => bool) private claimedBonus;\nmapping (address => uint) private rewardsForA;\n\nfunction untrustedWithdrawReward(address recipient) public {\n    uint amountToWithdraw = rewardsForA[recipient];\n    rewardsForA[recipient] = 0;\n    (bool success, ) = recipient.call.value(amountToWithdraw)(\"\");\n    require(success);\n}\n\nfunction untrustedGetFirstWithdrawalBonus(address recipient) public {\n    require(!claimedBonus[recipient]); // Each recipient should only be able to claim the bonus once\n\n    claimedBonus[recipient] = true;\n    rewardsForA[recipient] += 100;\n    untrustedWithdrawReward(recipient); // claimedBonus has been set to true, so reentry is impossible\n}\n```\n\nIn addition to the fix making reentry impossible,\n[untrusted functions have been marked](../development-recommendations/general/external-calls.md). This same\npattern repeats at every level: since `untrustedGetFirstWithdrawalBonus()` calls\n`untrustedWithdrawReward()`, which calls an external contract, you must also treat\n`untrustedGetFirstWithdrawalBonus()` as insecure.\n\nAnother solution often suggested is a [mutex](https://en.wikipedia.org/wiki/Mutual_exclusion). This\nallows you to \"lock\" some state so it can only be changed by the owner of the lock. A simple\nexample might look like this:\n\n```sol\n// Note: This is a rudimentary example, and mutexes are particularly useful where there is substantial logic and/or shared state\nmapping (address => uint) private balances;\nbool private lockBalances;\n\nfunction deposit() payable public returns (bool) {\n    require(!lockBalances);\n    lockBalances = true;\n    balances[msg.sender] += msg.value;\n    lockBalances = false;\n    return true;\n}\n\nfunction withdraw(uint amount) payable public returns (bool) {\n    require(!lockBalances && amount > 0 && balances[msg.sender] >= amount);\n    lockBalances = true;\n\n    (bool success, ) = msg.sender.call(amount)(\"\");\n\n    if (success) { // Normally insecure, but the mutex saves it\n      balances[msg.sender] -= amount;\n    }\n\n    lockBalances = false;\n    return true;\n}\n```\n\nIf the user tries to call `withdraw()` again before the first call finishes, the lock will prevent\nit from having any effect. This can be an effective pattern, but it gets tricky when you have\nmultiple contracts that need to cooperate. The following is insecure:\n\n```sol\n// INSECURE\ncontract StateHolder {\n    uint private n;\n    address private lockHolder;\n\n    function getLock() {\n        require(lockHolder == address(0));\n        lockHolder = msg.sender;\n    }\n\n    function releaseLock() {\n        require(msg.sender == lockHolder);\n        lockHolder = address(0);\n    }\n\n    function set(uint newState) {\n        require(msg.sender == lockHolder);\n        n = newState;\n    }\n}\n```\n\nAn attacker can call `getLock()`, and then never call `releaseLock()`. If they do this, then the\ncontract will be locked forever, and no further changes will be able to be made. If you use mutexes\nto protect against reentrancy, you will need to carefully ensure that there are no ways for a lock\nto be claimed and never released. (There are other potential dangers when programming with mutexes,\nsuch as deadlocks and livelocks. You should consult the large amount of literature already written\non mutexes, if you decide to go this route.)\n\nSee [SWC-107](https://swcregistry.io/docs/SWC-107)\n\n______________________________________________________________________\n\nAbove were examples of reentrancy involving the attacker executing malicious code *within a single\ntransaction*. The following are a different type of attack inherent to Blockchains: the fact that\n*the order of transactions themselves* (e.g. within a block) is easily subject to manipulation."
  },
  {
    "path": "docs/attacks/timestamp-dependence.md",
    "content": "Be aware that the timestamp of the block can be manipulated by the miner, and all direct and\nindirect uses of the timestamp should be considered.\n\n!!! Note\n    See the [Recommendations](../development-recommendations/solidity-specific/timestamp-dependence.md) section for design\n    considerations related to Timestamp Dependence.\n\n    See [SWC-116](https://swcregistry.io/docs/SWC-116)\n"
  },
  {
    "path": "docs/bug-bounty-programs.md",
    "content": "---\nhide:\n  - navigation\n---\n\n!!! tip\n\n    Looking for comprehensive information on setting up, managing, and operating a bug bounty program? Please refer to the [Smart Contract Security Field Guide's](https://scsfg.io/developers/bug-bounty/) bug bounty guide. This resource provides in-depth, up-to-date knowledge and strategies that are paramount for running a successful bug bounty program.\n\n\nOver the course of time Ethereum security has evolved to include different flavours of bug bounty programs which will be detailed below:\n\n### Bug Bounty Platforms\n\nThe first category are bug bounty platforms wherein a development team submits their project to a platform that either manages the programme for them or simply lists their project for exposure and reach toward interested security researchers. These platforms are further divided by type. The first are web3 native platforms hosting the majority of smart contract and frontend bug bounty programmes you'll find and the second are traditional platforms hosting majorly programmes with the frontend of centralized exchanges in scope. Finally, there are bounty collaboration platforms where developers are paid to code and implement new features or smart contracts.\n\nWeb3 native platforms:\n\n- [Immunefi](https://immunefi.com/)\n- [HackenProof](https://hackenproof.com/)\n\nTraditional platforms:\n\n- [HackerOne](https://hackerone.com/)\n- [Bugcrowd](https://www.bugcrowd.com/)\n\nBounty collaboration platforms:\n\n- [Gitcoin](https://gitcoin.co/explorer)\n\n### Crowd-sourced Security Solutions\n\nIn response to the high demand and low supply for professional smart contract security review firms, a few crowd sourced solutions have emerged to solve the issue. They all employ a bug bounty-esque model hence inclusion on this list. They call them \"audit contests\" with freelance security researchers scrambling to find and report vulnerabilities within a set time period i.e two weeks with payouts only being issued for successful findings. Examples are listed below:\n\n- [Code4rena](https://code4rena.com/)\n\n### Project Managed Bounties\n\nThe final category for now consists of bug bounty programmes that are directly managed by the project team itself and are often focused on smart contracts in their scope whether that's contributing to their features or breaking them.\n\nIssues and PRs are welcome to add new bounties, or remove those which are no longer\nactive.\n\n- [Airswap](https://medium.com/fluidity/airswap-bug-bounty-4d7ec41f3ea7)\n- [Ethereum Foundation](https://bounty.ethereum.org/#bounty-scope): Has a large scope, including\n  clients, Solidity and Vyper, and more.\n- [Etherscan.io](https://etherscan.io/bugbounty)\n- [ImmutableSoft](https://immutablesoft.github.io/ImmutableEcosystem/)\n- [0xProject](https://0x.org/docs/guides/bug-bounty-program#rewards)\n- [Parity](https://www.parity.io/bug-bounty/): Includes client and contract code\n"
  },
  {
    "path": "docs/development-recommendations/deprecated/constructor-naming.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n"
  },
  {
    "path": "docs/development-recommendations/deprecated/division-by-zero.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nPrior to version 0.4, Solidity [returns zero](https://github.com/ethereum/solidity/issues/670) and\ndoes not `throw` an exception when a number is divided by zero. Ensure you're running at least\nversion 0.4.\n"
  },
  {
    "path": "docs/development-recommendations/deprecated/functions-and-events.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\n### Differentiate functions and events (Solidity \\< 0.4.21)\n\nFavor capitalization and a prefix in front of events (we suggest *Log*), to prevent the risk of\nconfusion between functions and events. For functions, always start with a lowercase letter, except\nfor the constructor.\n\n```sol\n// bad\nevent Transfer() {}\nfunction transfer() {}\n\n// good\nevent LogTransfer() {}\nfunction transfer() external {}\n```\n\n!!! Note\n    In [v0.4.21](https://github.com/ethereum/solidity/blob/develop/Changelog.md#0421-2018-03-07) Solidity\n    introduced the `emit` keyword to indicate an event `emit EventName();`. As of 0.5.0, it is\n    required.\n"
  },
  {
    "path": "docs/development-recommendations/documentation/contact.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\n- Who to contact with issues\n- Names of programmers and/or other important parties\n- Chat room where questions can be asked\n"
  },
  {
    "path": "docs/development-recommendations/documentation/general.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nWhen launching a contract that will have substantial funds or is required to be mission critical,\nit is important to include proper documentation.\n"
  },
  {
    "path": "docs/development-recommendations/documentation/history.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\n- Testing (including usage stats, discovered bugs, length of testing)\n- People who have reviewed code (and their key feedback)\n"
  },
  {
    "path": "docs/development-recommendations/documentation/known-issues.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\n- Key risks with contract\n  - e.g., You can lose all your money, hacker can vote for certain outcomes\n- All known bugs/limitations\n- Potential attacks and mitigants\n- Potential conflicts of interest (e.g., will be using yourself, like Slock.it did with the DAO)\n"
  },
  {
    "path": "docs/development-recommendations/documentation/procedures.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\n- Action plan in case a bug is discovered (e.g., emergency options, public notification process,\n  etc.)\n- Wind down process if something goes wrong (e.g., funders will get percentage of your balance\n  before attack, from remaining funds)\n- Responsible disclosure policy (e.g., where to report bugs found, the rules of any bug bounty\n  program)\n- Recourse in case of failure (e.g., insurance, penalty fund, no recourse)\n"
  },
  {
    "path": "docs/development-recommendations/documentation/specification.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\n- Specs, diagrams, state machines, models, and other documentation that helps auditors, reviewers,\n  and the community understand what the system is intended to do.\n- Many bugs can be found just from the specifications, and they are the least costly to fix.\n- Rollout plans that include details listed [here](../precautions/deployment.md), and\n  target dates.\n"
  },
  {
    "path": "docs/development-recommendations/documentation/status.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\n- Where current code is deployed\n- Compiler version, flags used, and steps for verifying the deployed bytecode matches the source\n  code\n- Compiler versions and flags that will be used for the different phases of rollout.\n- Current status of deployed code (including outstanding issues, performance stats, etc.)\n"
  },
  {
    "path": "docs/development-recommendations/general/external-calls.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\n#### Use caution when making external calls\n\nCalls to untrusted contracts can introduce several unexpected risks or errors. External calls may\nexecute malicious code in that contract _or_ any other contract that it depends upon. As such,\nevery external call should be treated as a potential security risk. When it is not possible, or\nundesirable to remove external calls, use the recommendations in the rest of this section to\nminimize the danger.\n\n______________________________________________________________________\n\n#### Mark untrusted contracts\n\nWhen interacting with external contracts, name your variables, methods, and contract interfaces in\na way that makes it clear that interacting with them is potentially unsafe. This applies to your\nown functions that call external contracts.\n\n```sol\n// bad\nBank.withdraw(100); // Unclear whether trusted or untrusted\n\nfunction makeWithdrawal(uint amount) { // Isn't clear that this function is potentially unsafe\n    Bank.withdraw(amount);\n}\n\n// good\nUntrustedBank.withdraw(100); // untrusted external call\nTrustedBank.withdraw(100); // external but trusted bank contract maintained by XYZ Corp\n\nfunction makeUntrustedWithdrawal(uint amount) {\n    UntrustedBank.withdraw(amount);\n}\n```\n\n______________________________________________________________________\n\n#### Avoid state changes after external calls\n\nWhether using *raw calls* (of the form `someAddress.call()`) or *contract calls* (of the form\n`ExternalContract.someMethod()`), assume that malicious code might execute. Even if\n`ExternalContract` is not malicious, malicious code can be executed by any contracts *it* calls.\n\nOne particular danger is malicious code may hijack the control flow, leading to vulnerabilities due\nto reentrancy. (See [Reentrancy](../../attacks/reentrancy.md) for a fuller discussion of this\nproblem).\n\nIf you are making a call to an untrusted external contract, *avoid state changes after the call*.\nThis pattern is also sometimes known as the\n[checks-effects-interactions pattern](http://solidity.readthedocs.io/en/develop/security-considerations.html?highlight=check%20effects#use-the-checks-effects-interactions-pattern).\n\nSee [SWC-107](https://swcregistry.io/docs/SWC-107)\n\n______________________________________________________________________\n\n#### Don't use `transfer()` or `send()`.\n\n`.transfer()` and `.send()` forward exactly 2,300 gas to the recipient. The goal of this hardcoded\ngas stipend was to prevent [reentrancy vulnerabilities](../../attacks/reentrancy.md), but this only\nmakes sense under the assumption that gas costs are constant. Recently\n[EIP 1884](https://eips.ethereum.org/EIPS/eip-1884) was included in the Istanbul hard fork. One of\nthe changes included in EIP 1884 is an increase to the gas cost of the `SLOAD` operation, causing a\ncontract's fallback function to cost more than 2300 gas.\n\nIt's recommended to stop using `.transfer()` and `.send()` and instead use `.call()`.\n\n```\n// bad\ncontract Vulnerable {\n    function withdraw(uint256 amount) external {\n        // This forwards 2300 gas, which may not be enough if the recipient\n        // is a contract and gas costs change.\n        msg.sender.transfer(amount);\n    }\n}\n\n// good\ncontract Fixed {\n    function withdraw(uint256 amount) external {\n        // This forwards all available gas. Be sure to check the return value!\n        (bool success, ) = msg.sender.call.value(amount)(\"\");\n        require(success, \"Transfer failed.\");\n    }\n}\n```\n\nNote that `.call()` does nothing to mitigate reentrancy attacks, so other precautions must be\ntaken. To prevent reentrancy attacks, it is recommended that you use the\n[checks-effects-interactions pattern](https://solidity.readthedocs.io/en/develop/security-considerations.html?highlight=check%20effects#use-the-checks-effects-interactions-pattern).\n\n______________________________________________________________________\n\n#### Handle errors in external calls\n\nSolidity offers low-level call methods that work on raw addresses: `address.call()`,\n`address.callcode()`, `address.delegatecall()`, and `address.send()`. These low-level methods never\nthrow an exception, but will return `false` if the call encounters an exception. On the other hand,\n*contract calls* (e.g., `ExternalContract.doSomething()`) will automatically propagate a throw (for\nexample, `ExternalContract.doSomething()` will also `throw` if `doSomething()` throws).\n\nIf you choose to use the low-level call methods, make sure to handle the possibility that the call\nwill fail, by checking the return value.\n\n```sol\n// bad\nsomeAddress.send(55);\nsomeAddress.call.value(55)(\"\"); // this is doubly dangerous, as it will forward all remaining gas and doesn't check for result\nsomeAddress.call.value(100)(bytes4(sha3(\"deposit()\"))); // if deposit throws an exception, the raw call() will only return false and transaction will NOT be reverted\n\n// good\n(bool success, ) = someAddress.call.value(55)(\"\");\nif(!success) {\n    // handle failure code\n}\n\nExternalContract(someAddress).deposit.value(100)();\n```\n\nSee [SWC-104](https://swcregistry.io/docs/SWC-104)\n\n______________________________________________________________________\n\n#### Favor *pull* over *push* for external calls\n\nExternal calls can fail accidentally or deliberately. To minimize the damage caused by such\nfailures, it is often better to isolate each external call into its own transaction that can be\ninitiated by the recipient of the call. This is especially relevant for payments, where it is\nbetter to let users withdraw funds rather than push funds to them automatically. (This also reduces\nthe chance of [problems with the gas limit](../../attacks/denial-of-service.md).) Avoid\ncombining multiple ether transfers in a single transaction.\n\n```sol\n// bad\ncontract auction {\n    address highestBidder;\n    uint highestBid;\n\n    function bid() payable {\n        require(msg.value >= highestBid);\n\n        if (highestBidder != address(0)) {\n            (bool success, ) = highestBidder.call.value(highestBid)(\"\");\n            require(success); // if this call consistently fails, no one else can bid\n        }\n\n       highestBidder = msg.sender;\n       highestBid = msg.value;\n    }\n}\n\n// good\ncontract auction {\n    address highestBidder;\n    uint highestBid;\n    mapping(address => uint) refunds;\n\n    function bid() payable external {\n        require(msg.value >= highestBid);\n\n        if (highestBidder != address(0)) {\n            refunds[highestBidder] += highestBid; // record the refund that this user can claim\n        }\n\n        highestBidder = msg.sender;\n        highestBid = msg.value;\n    }\n\n    function withdrawRefund() external {\n        uint refund = refunds[msg.sender];\n        refunds[msg.sender] = 0;\n        (bool success, ) = msg.sender.call.value(refund)(\"\");\n        require(success);\n    }\n}\n```\n\nSee [SWC-128](https://swcregistry.io/docs/SWC-128)\n\n______________________________________________________________________\n\n#### Don't delegatecall to untrusted code\n\nThe `delegatecall` function is used to call functions from other contracts as if they belong to the\ncaller contract. Thus the callee may change the state of the calling address. This may be insecure.\nAn example below shows how using `delegatecall` can lead to the destruction of the contract and\nloss of its balance.\n\n```sol\ncontract Destructor\n{\n    function doWork() external\n    {\n        selfdestruct(0);\n    }\n}\n\ncontract Worker\n{\n    function doWork(address _internalWorker) public\n    {\n        // unsafe\n        _internalWorker.delegatecall(bytes4(keccak256(\"doWork()\")));\n    }\n}\n```\n\nIf `Worker.doWork()` is called with the address of the deployed `Destructor` contract as an\nargument, the `Worker` contract will self-destruct. Delegate execution only to trusted contracts,\nand **never to a user supplied address**.\n\n!!! Warning\n    Don't assume contracts are created with zero balance.  An attacker can send ether to the\n    address of a contract before it is created so contracts should not assume that their initial state\n    contains a zero balance. See\n    [issue 61](https://github.com/ConsenSys/smart-contract-best-practices/issues/61) for more details.\n\n    See [SWC-112](https://swcregistry.io/docs/SWC-112)\n"
  },
  {
    "path": "docs/development-recommendations/general/force-feeding.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nBeware of coding an invariant that strictly checks the balance of a contract.\n\nAn attacker can forcibly send ether to any account and this cannot be prevented (not even with a\nfallback function that does a `revert()`).\n\nThe attacker can do this by creating a contract, funding it with 1 wei, and invoking\n`selfdestruct(victimAddress)`. No code is invoked in `victimAddress`, so it cannot be prevented.\nThis is also true for block reward which is sent to the address of the miner, which can be any\narbitrary address.\n\nAlso, since contract addresses can be precomputed, ether can be sent to an address before the\ncontract is deployed.\n\nSee [SWC-132](https://swcregistry.io/docs/SWC-132)\n"
  },
  {
    "path": "docs/development-recommendations/general/negative-int.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nSolidity provides several types to work with signed integers. Like in most programming languages,\nin Solidity a signed integer with `N` bits can represent values from `-2^(N-1)` to `2^(N-1)-1`.\nThis means that there is no positive equivalent for the `MIN_INT`. Negation is implemented as\nfinding the two's complement of a number, so the negation of the most negative number\n[will result in the same number](https://en.wikipedia.org/wiki/Two%27s_complement#Most_negative_number).\n\nThis is true for all signed integer types in Solidity (`int8`, `int16`, ..., `int256`).\n\n```sol\ncontract Negation {\n    function negate8(int8 _i) public pure returns(int8) {\n        return -_i;\n    }\n\n    function negate16(int16 _i) public pure returns(int16) {\n        return -_i;\n    }\n\n    int8 public a = negate8(-128); // -128\n    int16 public b = negate16(-128); // 128\n    int16 public c = negate16(-32768); // -32768\n}\n```\n\nOne way to handle this is to check the value of a variable before negation and throw if it's equal\nto the `MIN_INT`. Another option is to make sure that the most negative number will never be\nachieved by using a type with a higher capacity (e.g. `int32` instead of `int16`).\n\nA similar issue with `int` types occurs when `MIN_INT` is multiplied or divided by `-1`.\n"
  },
  {
    "path": "docs/development-recommendations/general/participants.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nDo not make refund or claim processes dependent on a specific party performing a particular action\nwith no other way of getting the funds out. For example, in a rock-paper-scissors game, one common\nmistake is to not make a payout until both players submit their moves; however, a malicious player\ncan \"grief\" the other by simply never submitting their move - in fact, if a player sees the other\nplayer's revealed move and determines that they lost, they have no reason to submit their own move\nat all. This issue may also arise in the context of state channel settlement. When such situations\nare an issue, (1) provide a way of circumventing non-participating participants, perhaps through a\ntime limit, and (2) consider adding economic incentive for participants to submit information in\nall of the situations in which they are supposed to do so.\n"
  },
  {
    "path": "docs/development-recommendations/general/public-data.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nMany applications require submitted data to be private up until some point in time in order to\nwork. Games (eg. on-chain rock-paper-scissors) and auction mechanisms (eg. sealed-bid\n[Vickrey auctions](https://en.wikipedia.org/wiki/Vickrey_auction)) are two major categories of\nexamples. If you are building an application where privacy is an issue, make sure you avoid\nrequiring users to publish information too early. The best strategy is to use\n[commitment schemes](https://en.wikipedia.org/wiki/Commitment_scheme) with separate phases: first\ncommit using the hash of the values and in a later phase revealing the values.\n\nHowever, care must be taken to ensure that the hashed value stored isn't recognisable (and thus, de-mappable), as this would defeat the second purpose of hashing - preventing the reveal of such values. Here's an example:\n\nSay a smart contract allows 2 players to play rock-paper-scissors, and uses this commit-reveal scheme - both players have to send a hash of their move before either of them sends the last (game ending) transaction. Here's what the keccak256 hash of `rock` is: `10977e4d68108d418408bc9310b60fc6d0a750c63ccef42cfb0ead23ab73d102`. If you were playing, and you saw your opponent commiting this, wouldn't this tell you exactly what move your opponent has committed to? A safer implementation would be to hash not just the name of the move, but also, say, a user chosen salt. That would make the resulting salt non-recognisable.\n\nExamples:\n\n- In rock paper scissors, require both players to submit a hash of their intended move first, then\n  require both players to submit their move; if the submitted move does not match the hash throw it\n  out.\n- In an auction, require players to submit a hash of their bid value in an initial phase (along\n  with a deposit greater than their bid value), and then submit their auction bid value in the\n  second phase.\n- When developing an application that depends on a random number generator, the order should always\n  be *(1)* players submit moves, *(2)* random number generated, *(3)* players paid out. The method\n  by which random numbers are generated is itself an area of active research; current best-in-class\n  solutions include Bitcoin block headers (verified through http://btcrelay.org),\n  hash-commit-reveal schemes (ie. one party generates a number, publishes its hash to \"commit\" to\n  the value, and then reveals the value later) and [RANDAO](http://github.com/randao/randao). As\n  Ethereum is a deterministic protocol, no variable within the protocol could be used as an\n  unpredictable random number. Also, be aware that [miners are in some extent in control of the\n  `block.blockhash()`\n  value](https://ethereum.stackexchange.com/questions/419/when-can-blockhash-be-safely-used-for-a-random-number-when-would-it-be-unsafe).\n"
  },
  {
    "path": "docs/development-recommendations/index.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nThe development recommendations are split into six categories.\n\n| Category                                                          | Description                                                                                      |\n| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |\n| [General](./general/external-calls.md)                            | Guiding principles that should be kept in mind during development.                               |\n| [Precautions](./precautions/general.md)                           | Principles that prevent attacks in general or avoid excessive damage in the worst case scenario. |\n| [Solidity-specific](./solidity-specific/assert-require-revert.md) | Helpful tips when building smart contracts in Solidity - including interesting quirks.           |\n| [Token-specifc](./token-specific/standardization.md)              | Recommendations to honour when dealing with or implementing tokens                               |\n| [Documentation](./documentation/general.md)                       | Guidelines on how to properly document smart contracts and the processes surrounding them.       |\n| [Deprecated](./deprecated/division-by-zero.md)                    | Vulnerabilities that were applicable in the past but can be reasonably excluded nowadays.        |\n\n"
  },
  {
    "path": "docs/development-recommendations/precautions/circuit-breakers.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nCircuit breakers stop execution if certain conditions are met, and can be useful when new errors\nare discovered. For example, most actions may be suspended in a contract if a bug is discovered,\nand the only action now active is a withdrawal. You can either give certain trusted parties the\nability to trigger the circuit breaker or else have programmatic rules that automatically trigger\nthe certain breaker when certain conditions are met.\n\nExample:\n\n```sol\nbool private stopped = false;\naddress private owner;\n\nmodifier isAdmin() {\n    require(msg.sender == owner);\n    _;\n}\n\nfunction toggleContractActive() isAdmin public {\n    // You can add an additional modifier that restricts stopping a contract to be based on another action, such as a vote of users\n    stopped = !stopped;\n}\n\nmodifier stopInEmergency { if (!stopped) _; }\nmodifier onlyInEmergency { if (stopped) _; }\n\nfunction deposit() stopInEmergency public {\n    // some code\n}\n\nfunction withdraw() onlyInEmergency public {\n    // some code\n}\n```\n"
  },
  {
    "path": "docs/development-recommendations/precautions/deployment.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nContracts should have a substantial and prolonged testing period - before substantial money is put\nat risk.\n\nAt minimum, you should:\n\n- Have a full test suite with 100% test coverage (or close to it)\n- Deploy on your own testnet\n- Deploy on the public testnet with substantial testing and bug bounties\n- Exhaustive testing should allow various players to interact with the contract at volume\n- Deploy on the mainnet in beta, with limits to the amount at risk\n\n##### Automatic Deprecation\n\nDuring testing, you can force an automatic deprecation by preventing any actions, after a certain\ntime period. For example, an alpha contract may work for several weeks and then automatically shut\ndown all actions, except for the final withdrawal.\n\n```sol\nmodifier isActive() {\n    require(block.number <= SOME_BLOCK_NUMBER);\n    _;\n}\n\nfunction deposit() public isActive {\n    // some code\n}\n\nfunction withdraw() public {\n    // some code\n}\n```\n\n##### Restrict amount of Ether per user/contract\n\nIn the early stages, you can restrict the amount of Ether for any user (or for the entire contract)\n\\- reducing the risk.\n"
  },
  {
    "path": "docs/development-recommendations/precautions/general.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nAs we discussed in the [General Philosophy](../../general-philosophy/index.md) section, it is not enough to\nprotect yourself against the known attacks. Since the cost of failure on a blockchain can be very\nhigh, you must also adapt the way you write software, to account for that risk.\n\nThe approach we advocate is to \"prepare for failure\". It is impossible to know in advance whether\nyour code is secure. However, you can architect your contracts in a way that allows them to fail\ngracefully, and with minimal damage. This section presents a variety of techniques that will help\nyou prepare for failure.\n\nNote: There's always a risk when you add a new component to your system. A badly designed fail-safe\ncould itself become a vulnerability, as can the interaction between a number of well-designed\nfail-safes. Be thoughtful about each technique you use in your contracts, and consider carefully\nhow they work together to create a robust system.\n"
  },
  {
    "path": "docs/development-recommendations/precautions/rate-limiting.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nRate limiting halts or requires approval for substantial changes. For example, a depositor may only\nbe allowed to withdraw a certain amount or percentage of total deposits over a certain time period\n(e.g., max 100 ether over 1 day) - additional withdrawals in that time period may fail or require\nsome sort of special approval. Or the rate limit could be at the contract level, with only a\ncertain amount of tokens issued by the contract over a time period.\n\nExample:\n\n```sol\nuint internal period; // how many blocks before limit resets\nuint internal limit; // max ether to withdraw per period\nuint internal currentPeriodEnd; // block which the current period ends at\nuint internal currentPeriodAmount; // amount already withdrawn this period\n\nconstructor(uint _period, uint _limit) public {\n    period = _period;\n    limit = _limit;\n\n    currentPeriodEnd = block.number + period;\n}\n\nfunction withdraw(uint amount) public {\n    // Update period before proceeding\n    updatePeriod();\n\n    // Prevent overflow\n    uint totalAmount = currentPeriodAmount + amount;\n    require(totalAmount >= currentPeriodAmount, 'overflow');\n\n    // Disallow withdraws that exceed current rate limit\n    require(currentPeriodAmount + amount < limit, 'exceeds period limit');\n    currentPeriodAmount += amount;\n    msg.sender.transfer(amount);\n}\n\nfunction updatePeriod() internal {\n    if(currentPeriodEnd < block.number) {\n        currentPeriodEnd = block.number + period;\n        currentPeriodAmount = 0;\n    }\n}\n```\n"
  },
  {
    "path": "docs/development-recommendations/precautions/safe-haven.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nSome tips for running bounty programs:\n\n- Decide which currency bounties will be distributed in (BTC and/or ETH)\n- Decide on an estimated total budget for bounty rewards\n- From the budget, determine three tiers of rewards:\n  - smallest reward you are willing to give out\n  - highest reward that's usually awardable\n  - an extra range to be awarded in case of very severe vulnerabilities\n- Determine who the bounty judges are (3 may be ideal typically)\n- Lead developer should probably be one of the bounty judges\n- When a bug report is received, the lead developer, with advice from judges, should evaluate the\n  severity of the bug\n- Work at this stage should be in a private repo, and the issue filed on Github\n- If it's a bug that should be fixed, in the private repo, a developer should write a test case,\n  which should fail and thus confirm the bug\n- Developer should implement the fix and ensure the test now passes; writing additional tests as\n  needed\n- Show the bounty hunter the fix; merge the fix back to the public repo is one way\n- Determine if bounty hunter has any other feedback about the fix\n- Bounty judges determine the size of the reward, based on their evaluation of both the\n  *likelihood* and *impact* of the bug.\n- Keep bounty participants informed throughout the process, and then strive to avoid delays in\n  sending them their reward\n\nFor an example of the three tiers of rewards, see\n[Ethereum's Bounty Program](https://bounty.ethereum.org):\n\n> The value of rewards paid out will vary depending on severity of impact. Rewards for minor\n> 'harmless' bugs start at 0.05 BTC. Major bugs, for example leading to consensus issues, will be\n> rewarded up to 5 BTC. Much higher rewards are possible (up to 25 BTC) in case of very severe\n> vulnerabilities.\n"
  },
  {
    "path": "docs/development-recommendations/precautions/speed-bumps.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nSpeed bumps slow down actions, so that if malicious actions occur, there is time to recover. For\nexample, [The DAO](https://github.com/slockit/DAO/) required 27 days between a successful request\nto split the DAO and the ability to do so. This ensured the funds were kept within the contract,\nincreasing the likelihood of recovery. In the case of the DAO, there was no effective action that\ncould be taken during the time given by the speed bump, but in combination with our other\ntechniques, they can be quite effective.\n\nExample:\n\n```sol\nstruct RequestedWithdrawal {\n    uint amount;\n    uint time;\n}\n\nmapping (address => uint) private balances;\nmapping (address => RequestedWithdrawal) private requestedWithdrawals;\nuint constant withdrawalWaitPeriod = 28 days; // 4 weeks\n\nfunction requestWithdrawal() public {\n    if (balances[msg.sender] > 0) {\n        uint amountToWithdraw = balances[msg.sender];\n        balances[msg.sender] = 0; // for simplicity, we withdraw everything;\n        // presumably, the deposit function prevents new deposits when withdrawals are in progress\n\n        requestedWithdrawals[msg.sender] = RequestedWithdrawal({\n            amount: amountToWithdraw,\n            time: block.timestamp\n        });\n    }\n}\n\nfunction withdraw() public {\n    if(requestedWithdrawals[msg.sender].amount > 0 && block.timestamp > requestedWithdrawals[msg.sender].time + withdrawalWaitPeriod) {\n        uint amountToWithdraw = requestedWithdrawals[msg.sender].amount;\n        requestedWithdrawals[msg.sender].amount = 0;\n\n        require(msg.sender.send(amountToWithdraw));\n    }\n}\n```\n"
  },
  {
    "path": "docs/development-recommendations/precautions/upgradeability.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nCode will need to be changed if errors are discovered or if improvements need to be made. It is no\ngood to discover a bug, but have no way to deal with it.\n\nDesigning an effective upgrade system for smart contracts is an area of active research, and we\nwon't be able to cover all of the complications in this document. However, two basic approaches are\nmost commonly used. The simpler of the two is to have a registry contract that holds the address of\nthe latest version of the contract. A more seamless approach for contract users is to have a\ncontract that forwards calls and data onto the latest version of the contract.\n\nWhatever the technique, it's important to have modularization and good separation between\ncomponents, so that code changes do not break functionality, orphan data, or require substantial\ncosts to port. In particular, it is usually beneficial to separate complex logic from your data\nstorage, so that you do not have to recreate all of the data in order to change the functionality.\n\nIt's also critical to have a secure way for parties to decide to upgrade the code. Depending on\nyour contract, code changes may need to be approved by a single trusted party, a group of members,\nor a vote of the full set of stakeholders. If this process can take some time, you will want to\nconsider if there are other ways to react more quickly in case of an attack, such as an\n[emergency stop or circuit-breaker](./circuit-breakers.md).\n\nRegardless of your approach, it is important to have some way to upgrade your contracts, or they\nwill become unusable when the inevitable bugs are discovered in them.\n\n#### Example 1: Use a registry contract to store the latest version of a contract\n\nIn this example, the calls aren't forwarded, so users should fetch the current address each time\nbefore interacting with it.\n\n```sol\npragma solidity ^0.5.0;\n\ncontract SomeRegister {\n    address backendContract;\n    address[] previousBackends;\n    address owner;\n\n    constructor() {\n        owner = msg.sender;\n    }\n\n    modifier onlyOwner() {\n        require(msg.sender == owner)\n        _;\n    }\n\n    function changeBackend(address newBackend) public\n    onlyOwner()\n    returns (bool)\n    {\n        if(newBackend != address(0) && newBackend != backendContract) {\n            previousBackends.push(backendContract);\n            backendContract = newBackend;\n            return true;\n        }\n\n        return false;\n    }\n}\n```\n\nThere are two main disadvantages to this approach:\n\n1. Users must always look up the current address, and anyone who fails to do so risks using an old\n   version of the contract\n1. You will need to think carefully about how to deal with the contract data when you replace the\n   contract\n\nThe alternate approach is to have a contract forward calls and data to the latest version of the\ncontract:\n\n#### Example 2: [Use a `DELEGATECALL`](http://ethereum.stackexchange.com/questions/2404/upgradeable-contracts) to forward data and calls\n\nThis approach relies on using the\n[fallback function](https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function) (in\n`Relay` contract) to forward the calls to a target contract (`LogicContract`) using\n[delegatecall](https://solidity.readthedocs.io/en/latest/introduction-to-smart-contracts.html#delegatecall-callcode-and-libraries).\nRemember that `delegatecall` is a special function in Solidity that executes the logic of the\ncalled address (`LogicContract`) in the context of the calling contract (`Relay`), so *\"storage,\ncurrent address and balance still refer to the calling contract , only the code is taken from the\ncalled address\"*.\n\n```sol\npragma solidity ^0.5.0;\n\ncontract Relay {\n    address public currentVersion;\n    address public owner;\n\n    modifier onlyOwner() {\n        require(msg.sender == owner);\n        _;\n    }\n\n    constructor(address initAddr) {\n        require(initAddr != address(0));\n        currentVersion = initAddr;\n        owner = msg.sender; // this owner may be another contract with multisig, not a single contract owner\n    }\n\n    function changeContract(address newVersion) public\n    onlyOwner()\n    {\n        require(newVersion != address(0));\n        currentVersion = newVersion;\n    }\n\n    fallback() external payable {\n        (bool success, ) = address(currentVersion).delegatecall(msg.data);\n        require(success);\n    }\n}\n```\n\n```sol\ncontract LogicContract {\n    address public currentVersion;\n    address public owner;\n    uint public counter;\n\n    function incrementCounter() {\n        counter++;\n    }\n}\n```\n\nThis simple version of the pattern cannot return values from `LogicContract`'s functions, only\nforward them, which limits its applicability. More complex implementations attempt to solve this\nwith in-line assembly code and a registry of return sizes. They are commonly referred to as\n[Proxy Patterns](https://blog.openzeppelin.com/proxy-patterns/), but are also known as\n[Router](https://github.com/PeterBorah/ether-router),\n[Dispatcher](https://gist.github.com/Arachnid/4ca9da48d51e23e5cfe0f0e14dd6318f) and Relay. Each\nimplementation variant introduces a different set of complexity, risks and limitations.\n\nYou must be extremely careful with how you store data with this method. If your new contract has a\ndifferent storage layout than the first, your data may end up corrupted. When using more complex\nimplementations of `delegatecall`, you should carefully consider and understand\\*:\n\n- How the EVM handles the\n  [layout of state variables in storage](https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html),\n  including packing multiple variables into a single storage slot if possible\n- How and why\n  [the order of inheritance](https://github.com/OpenZeppelin/openzeppelin-sdk/issues/37) impacts\n  the storage layout\n- Why the called contract (`LogicContract`) must have the same storage layout of the calling\n  contract (`Relay`), and only append new variables to the storage (see\n  [Background on delegatecall](https://blog.trailofbits.com/2018/09/05/contract-upgrade-anti-patterns/))\n- Why a new version of the called contract (`LogicContract`)\n  [must have the same storage layout as the previous version](https://github.com/OpenZeppelin/openzeppelin-sdk/issues/37),\n  and only append new variables to the storage\n- [How a contract's constructor can affect upgradeability](https://blog.openzeppelin.com/towards-frictionless-upgradeability/)\n- How the ABI specifies\n  [function selectors](https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html?highlight=signature#function-selector)\n  and how\n  [function-name collision](https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357)\n  can be used to exploit a contract that uses `delegatecall`\n- How `delegatecall` to a non-existent contract will return true even if the called contract does\n  not exist. For more details see\n  [Breaking the proxy pattern](https://blog.trailofbits.com/2018/09/05/contract-upgrade-anti-patterns/)\n  and Solidity docs on\n  [Error handling](https://solidity.readthedocs.io/en/latest/control-structures.html#error-handling-assert-require-revert-and-exceptions).\n- Remember the\n  [importance of immutability to achieve trustlessness](https://consensys.net/diligence/blog/2019/01/upgradeability-is-a-bug/)\n\n\\* *Extended from\n[Proxy pattern recommendations section](https://blog.trailofbits.com/2018/09/05/contract-upgrade-anti-patterns/)*\n"
  },
  {
    "path": "docs/development-recommendations/solidity-specific/abstract-vs-interfaces.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nBe aware of the tradeoffs between **abstract contracts** and **interfaces**.\n\nBoth interfaces and abstract contracts provide one with a customizable and re-usable approach for\nsmart contracts. Interfaces, which were introduced in Solidity 0.4.11, are similar to abstract\ncontracts but cannot have any functions implemented. Interfaces also have limitations such as not\nbeing able to access storage or inherit from other interfaces which generally makes abstract\ncontracts more practical. Although, interfaces are certainly useful for designing contracts prior\nto implementation. Additionally, it is important to keep in mind that if a contract inherits from\nan abstract contract it must implement all non-implemented functions via overriding or it will be\nabstract as well.\n"
  },
  {
    "path": "docs/development-recommendations/solidity-specific/assert-require-revert.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\n#### Enforce invariants with `assert()`\n\nAn assert guard triggers when an assertion fails - such as an invariant property changing. For\nexample, the token to ether issuance ratio, in a token issuance contract, may be fixed. You can\nverify that this is the case at all times with an `assert()`. Assert guards should often be\ncombined with other techniques, such as pausing the contract and allowing upgrades. (Otherwise, you\nmay end up stuck, with an assertion that is always failing.)\n\nExample:\n\n```sol\ncontract Token {\n    mapping(address => uint) public balanceOf;\n    uint public totalSupply;\n\n    function deposit() public payable {\n        balanceOf[msg.sender] += msg.value;\n        totalSupply += msg.value;\n        assert(address(this).balance >= totalSupply);\n    }\n}\n```\n\nNote that the assertion is *not* a strict equality of the balance because the contract can be\n[forcibly sent ether](#remember-that-ether-can-be-forcibly-sent-to-an-account) without going\nthrough the `deposit()` function!\n\n\n#### Use `assert()`, `require()`, `revert()` properly\n\n!!! Info\n    The convenience functions **assert** and **require** can be used to check for conditions and throw an exception if the condition is not met.\n\nThe **assert** function should only be used to test for internal errors, and to check invariants.\n\nThe [**require** function should be used to ensure valid conditions](https://docs.soliditylang.org/en/latest/control-structures.html#panic-via-assert-and-error-via-require), such as inputs, or contract state variables are met, or to validate return values from calls to external contracts.\n\nFollowing this paradigm allows formal analysis tools to verify that the invalid opcode can never be\nreached: meaning no invariants in the code are violated and that the code is formally verified.\n\n```sol\npragma solidity ^0.5.0;\n\ncontract Sharer {\n    function sendHalf(address payable addr) public payable returns (uint balance) {\n        require(msg.value % 2 == 0, \"Even value required.\"); //Require() can have an optional message string\n        uint balanceBeforeTransfer = address(this).balance;\n        (bool success, ) = addr.call.value(msg.value / 2)(\"\");\n        require(success);\n        // Since we reverted if the transfer failed, there should be\n        // no way for us to still have half of the money.\n        assert(address(this).balance == balanceBeforeTransfer - msg.value / 2); // used for internal error checking\n        return address(this).balance;\n    }\n}\n```\n\nSee [SWC-110](https://swcregistry.io/docs/SWC-110) & [SWC-123](https://swcregistry.io/docs/SWC-123)\n"
  },
  {
    "path": "docs/development-recommendations/solidity-specific/complex-inheritance.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nWhen utilizing multiple inheritance in Solidity, it is important to understand how the compiler\ncomposes the inheritance graph.\n\n```sol\n\ncontract Final {\n    uint public a;\n    function Final(uint f) public {\n        a = f;\n    }\n}\n\ncontract B is Final {\n    int public fee;\n\n    function B(uint f) Final(f) public {\n    }\n    function setFee() public {\n        fee = 3;\n    }\n}\n\ncontract C is Final {\n    int public fee;\n\n    function C(uint f) Final(f) public {\n    }\n    function setFee() public {\n        fee = 5;\n    }\n}\n\ncontract A is B, C {\n  function A() public B(3) C(5) {\n      setFee();\n  }\n}\n```\n\nWhen a contract is deployed, the compiler will *linearize* the inheritance from right to left\n(after the keyword _is_ the parents are listed from the most base-like to the most derived). Here\nis contract A's linearization:\n\n**Final \\<- B \\<- C \\<- A**\n\nThe consequence of the linearization will yield a `fee` value of 5, since C is the most derived\ncontract. This may seem obvious, but imagine scenarios where C is able to shadow crucial functions,\nreorder boolean clauses, and cause the developer to write exploitable contracts. Static analysis\ncurrently does not raise issue with overshadowed functions, so it must be manually inspected.\n\nFor more on security and inheritance, check out this\n[article](https://pdaian.com/blog/solidity-anti-patterns-fun-with-inheritance-dag-abuse/)\n\nTo help contribute, Solidity's Github has a\n[project](https://github.com/ethereum/solidity/projects/9#card-8027020) with all\ninheritance-related issues.\n\nSee [SWC-125](https://swcregistry.io/docs/SWC-125)\n"
  },
  {
    "path": "docs/development-recommendations/solidity-specific/event-monitoring.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nIt can be useful to have a way to monitor the contract's activity after it was deployed. One way to\naccomplish this is to look at all transactions of the contract, however that may be insufficient,\nas message calls between contracts are not recorded in the blockchain. Moreover, it shows only the\ninput parameters, not the actual changes being made to the state. Also, events could be used to\ntrigger functions in the user interface.\n\n```sol\ncontract Charity {\n    mapping(address => uint) balances;\n\n    function donate() payable public {\n        balances[msg.sender] += msg.value;\n    }\n}\n\ncontract Game {\n    function buyCoins() payable public {\n        // 5% goes to charity\n        charity.donate.value(msg.value / 20)();\n    }\n}\n```\n\nHere, `Game` contract will make an internal call to `Charity.donate()`. This transaction won't\nappear in the external transaction list of `Charity`, but only visible in the internal\ntransactions.\n\nAn event is a convenient way to log something that happened in the contract. Events that were\nemitted stay in the blockchain along with the other contract data and they are available for future\naudit. Here is an improvement to the example above, using events to provide a history of the\nCharity's donations.\n\n```sol\ncontract Charity {\n    // define event\n    event LogDonate(uint _amount);\n\n    mapping(address => uint) balances;\n\n    function donate() payable public {\n        balances[msg.sender] += msg.value;\n        // emit event\n        emit LogDonate(msg.value);\n    }\n}\n\ncontract Game {\n    function buyCoins() payable public {\n        // 5% goes to charity\n        charity.donate.value(msg.value / 20)();\n    }\n}\n\n```\n\nHere, all transactions that go through the `Charity` contract, either directly or not, will show up\nin the event list of that contract along with the amount of donated money.\n\n______________________________________________________________________\n\n!!! Note \"Prefer newer Solidity constructs\"\n    Prefer constructs/aliases such as `selfdestruct` (over `suicide`) and `keccak256` (over `sha3`).  Patterns like `require(msg.sender.send(1 ether))` can also be simplified to using `transfer()`, as in `msg.sender.transfer(1 ether)`. Check out [Solidity Change log](https://github.com/ethereum/solidity/blob/develop/Changelog.md) for more similar changes.\n"
  },
  {
    "path": "docs/development-recommendations/solidity-specific/extcodesize-checks.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nAvoid using `extcodesize` to check for Externally Owned Accounts.\n\nThe following modifier (or a similar check) is often used to verify whether a call was made from an\nexternally owned account (EOA) or a contract account:\n\n```sol\n// bad\nmodifier isNotContract(address _a) {\n  uint size;\n  assembly {\n    size := extcodesize(_a)\n  }\n    require(size == 0);\n     _;\n}\n```\n\nThe idea is straightforward: if an address contains code, it's not an EOA but a contract account.\nHowever, **a contract does not have source code available during construction**. This means that\nwhile the constructor is running, it can make calls to other contracts, but `extcodesize` for its\naddress returns zero. Below is a minimal example that shows how this check can be circumvented:\n\n```sol\ncontract OnlyForEOA {    \n    uint public flag;\n\n    // bad\n    modifier isNotContract(address _a){\n        uint len;\n        assembly { len := extcodesize(_a) }\n        require(len == 0);\n        _;\n    }\n\n    function setFlag(uint i) public isNotContract(msg.sender){\n        flag = i;\n    }\n}\n\ncontract FakeEOA {\n    constructor(address _a) public {\n        OnlyForEOA c = OnlyForEOA(_a);\n        c.setFlag(1);\n    }\n}\n```\n\nBecause contract addresses can be pre-computed, this check could also fail if it checks an address\nwhich is empty at block `n`, but which has a contract deployed to it at some block greater than\n`n`.\n\n!!! Warning \"This issue is nuanced.\"\n    If your goal is to prevent other contracts from being able to call your contract, the `extcodesize` check is probably sufficient. An alternative approach is to check the value of `(tx.origin == msg.sender)`, though this also [has drawbacks](../../development-recommendations/solidity-specific/tx-origin.md).\n\n    There may be other situations in which the `extcodesize` check serves your purpose. Describing all of them here is out of scope. Understand the underlying behaviors of the EVM and use your judgement.\n"
  },
  {
    "path": "docs/development-recommendations/solidity-specific/fallback-functions.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\n#### Keep fallback functions simple\n\n[Fallback functions](http://solidity.readthedocs.io/en/latest/contracts.html#fallback-function) are\ncalled when a contract is sent a message with no arguments (or when no function matches), and only\nhas access to 2,300 gas when called from a `.send()` or `.transfer()`. If you wish to be able to\nreceive Ether from a `.send()` or `.transfer()`, the most you can do in a fallback function is log\nan event. Use a proper function if a computation of more gas is required.\n\n```sol\n// bad\nfunction() payable { balances[msg.sender] += msg.value; }\n\n// good\nfunction deposit() payable external { balances[msg.sender] += msg.value; }\n\nfunction() payable { require(msg.data.length == 0); emit LogDepositReceived(msg.sender); }\n```\n\n#### Check data length in fallback functions\n\nSince the\n[fallback functions](http://solidity.readthedocs.io/en/latest/contracts.html#fallback-function) is\nnot only called for plain ether transfers (without data) but also when no other function matches,\nyou should check that the data is empty if the fallback function is intended to be used only for\nthe purpose of logging received Ether. Otherwise, callers will not notice if your contract is used\nincorrectly and functions that do not exist are called.\n\n```sol\n// bad\nfunction() payable { emit LogDepositReceived(msg.sender); }\n\n// good\nfunction() payable { require(msg.data.length == 0); emit LogDepositReceived(msg.sender); }\n```\n"
  },
  {
    "path": "docs/development-recommendations/solidity-specific/integer-division.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nAll integer division rounds down to the nearest integer. If you need more precision, consider using\na multiplier, or store both the numerator and denominator.\n\n(In the future, Solidity will have a\n[fixed-point](https://solidity.readthedocs.io/en/develop/types.html#fixed-point-numbers) type,\nwhich will make this easier.)\n\n```sol\n// bad\nuint x = 5 / 2; // Result is 2, all integer division rounds DOWN to the nearest integer\n```\n\nUsing a multiplier prevents rounding down, this multiplier needs to be accounted for when working\nwith x in the future:\n\n```sol\n// good\nuint multiplier = 10;\nuint x = (5 * multiplier) / 2;\n```\n\nStoring the numerator and denominator means you can calculate the result of `numerator/denominator`\noff-chain:\n\n```sol\n// good\nuint numerator = 5;\nuint denominator = 2;\n```\n"
  },
  {
    "path": "docs/development-recommendations/solidity-specific/interface-types.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nWhen a function takes a contract address as an argument, it is better to pass an interface or\ncontract type rather than a raw `address`. If the function is called elsewhere within the source\ncode, the compiler will provide additional type safety guarantees.\n\nHere we see two alternatives:\n\n```sol\ncontract Validator {\n    function validate(uint) external returns(bool);\n}\n\ncontract TypeSafeAuction {\n    // good\n    function validateBet(Validator _validator, uint _value) internal returns(bool) {\n        bool valid = _validator.validate(_value);\n        return valid;\n    }\n}\n\ncontract TypeUnsafeAuction {\n    // bad\n    function validateBet(address _addr, uint _value) internal returns(bool) {\n        Validator validator = Validator(_addr);\n        bool valid = validator.validate(_value);\n        return valid;\n    }\n}\n```\n\nThe benefits of using the `TypeSafeAuction` contract above can then be seen from the following\nexample. If `validateBet()` is called with an `address` argument, or a contract type other than\n`Validator`, the compiler will throw this error:\n\n```sol\ncontract NonValidator{}\n\ncontract Auction is TypeSafeAuction {\n    NonValidator nonValidator;\n\n    function bet(uint _value) {\n        bool valid = validateBet(nonValidator, _value); // TypeError: Invalid type for argument in function call.\n                                                        // Invalid implicit conversion from contract NonValidator\n                                                        // to contract Validator requested.\n    }\n}\n```\n"
  },
  {
    "path": "docs/development-recommendations/solidity-specific/locking-pragmas.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nContracts should be deployed with the same compiler version and flags that they have been tested\nthe most with. Locking the pragma helps ensure that contracts do not accidentally get deployed\nusing, for example, the latest compiler which may have higher risks of undiscovered bugs. Contracts\nmay also be deployed by others and the pragma indicates the compiler version intended by the\noriginal authors.\n\n```sol\n// bad\npragma solidity ^0.4.4;\n\n\n// good\npragma solidity 0.4.4;\n```\n\nNote: a floating pragma version (ie. `^0.4.25`) will compile fine with `0.4.26-nightly.2018.9.25`,\nhowever nightly builds should never be used to compile code for production.\n\n!!! Warning\n    Pragma statements can be allowed to float when a contract is intended for consumption\n    by other developers, as in the case with contracts in a library or EthPM package. Otherwise, the\n    developer would need to manually update the pragma in order to compile locally.\n\n    See [SWC-103](https://swcregistry.io/docs/SWC-103)\n"
  },
  {
    "path": "docs/development-recommendations/solidity-specific/modifiers-as-guards.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nThe code inside a modifier is usually executed before the function body, so any state changes or\nexternal calls will violate the\n[Checks-Effects-Interactions](https://solidity.readthedocs.io/en/develop/security-considerations.html#use-the-checks-effects-interactions-pattern)\npattern. Moreover, these statements may also remain unnoticed by the developer, as the code for\nmodifier may be far from the function declaration. For example, an external call in modifier can\nlead to the reentrancy attack:\n\n```sol\ncontract Registry {\n    address owner;\n\n    function isVoter(address _addr) external returns(bool) {\n        // Code\n    }\n}\n\ncontract Election {\n    Registry registry;\n\n    modifier isEligible(address _addr) {\n        require(registry.isVoter(_addr));\n        _;\n    }\n\n    function vote() isEligible(msg.sender) public {\n        // Code\n    }\n}\n```\n\nIn this case, the `Registry` contract can make a reentrancy attack by calling `Election.vote()`\ninside `isVoter()`.\n\n!!! Note\n    Use [modifiers](https://solidity.readthedocs.io/en/develop/contracts.html#function-modifiers) to\n    replace duplicate condition checks in multiple functions, such as `isOwner()`, otherwise use\n    `require` or `revert` inside the function. This makes your smart contract code more readable and\n    easier to audit.\n"
  },
  {
    "path": "docs/development-recommendations/solidity-specific/payability.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nStarting from Solidity `0.4.0`, every function that is receiving ether must use `payable` modifier,\notherwise if the transaction has `msg.value > 0` will revert\n([except when forced](../../attacks/force-feeding.md)).\n\n!!! Note\n    Something that might not be obvious: The `payable` modifier only applies to calls from *external* contracts. If I call a non-payable function in the payable function in the same contract, the non-payable function won't fail, though `msg.value` is still set.\n"
  },
  {
    "path": "docs/development-recommendations/solidity-specific/shadowing.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nIt is currently possible to [shadow](https://en.wikipedia.org/wiki/Variable_shadowing) built-in\nglobals in Solidity. This allows contracts to override the functionality of built-ins such as `msg`\nand `revert()`. Although this [is intended](https://github.com/ethereum/solidity/issues/1249), it\ncan mislead users of a contract as to the contract's true behavior.\n\n```sol\ncontract PretendingToRevert {\n    function revert() internal constant {}\n}\n\ncontract ExampleContract is PretendingToRevert {\n    function somethingBad() public {\n        revert();\n    }\n}\n```\n\nContract users (and auditors) should be aware of the full smart contract source code of any\napplication they intend to use.\n"
  },
  {
    "path": "docs/development-recommendations/solidity-specific/timestamp-dependence.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nThere are three main considerations when using a timestamp to execute a critical function in a\ncontract, especially when actions involve fund transfer.\n\n#### Timestamp Manipulation\n\nBe aware that the timestamp of the block can be manipulated by a miner. Consider this\n[contract](https://etherscan.io/address/0xcac337492149bdb66b088bf5914bedfbf78ccc18#code):\n\n```sol\n\nuint256 constant private salt =  block.timestamp;\n\nfunction random(uint Max) constant private returns (uint256 result){\n    //get the best seed for randomness\n    uint256 x = salt * 100/Max;\n    uint256 y = salt * block.number/(salt % 5) ;\n    uint256 seed = block.number/3 + (salt % 300) + Last_Payout + y;\n    uint256 h = uint256(block.blockhash(seed));\n\n    return uint256((h / x)) % Max + 1; //random number between 1 and Max\n}\n```\n\nWhen the contract uses the timestamp to seed a random number, the miner can actually post a\ntimestamp within 15 seconds of the block being validated, effectively allowing the miner to\nprecompute an option more favorable to their chances in the lottery. Timestamps are not random and\nshould not be used in that context.\n\n#### The 15-second Rule\n\nThe [Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf) (Ethereum's reference\nspecification) does not specify a constraint on how much blocks can drift in time, but\n[it does specify](https://ethereum.stackexchange.com/a/5926/46821) that each timestamp should be\nbigger than the timestamp of its parent. Popular Ethereum protocol implementations\n[Geth](https://github.com/ethereum/go-ethereum/blob/4e474c74dc2ac1d26b339c32064d0bac98775e77/consensus/ethash/consensus.go#L45)\nand\n[Parity](https://github.com/paritytech/parity-ethereum/blob/73db5dda8c0109bb6bc1392624875078f973be14/ethcore/src/verification/verification.rs#L296-L307)\nboth reject blocks with timestamp more than 15 seconds in future. Therefore, a good rule of thumb\nin evaluating timestamp usage is:\n\n!!! Note\n    If the scale of your time-dependent event can vary by 15 seconds and maintain integrity,\n    it is safe to use a `block.timestamp`.\n\n#### Avoid using `block.number` as a timestamp\n\nIt is possible to estimate a time delta using the `block.number` property and\n[average block time](https://etherscan.io/chart/blocktime), however this is not future proof as\nblock times may change (such as\n[fork reorganisations](https://blog.ethereum.org/2015/08/08/chain-reorganisation-depth-expectations/)\nand the [difficulty bomb](https://github.com/ethereum/EIPs/issues/649)). In a sale spanning days,\nthe 15-second rule allows one to achieve a more reliable estimate of time.\n\nSee [SWC-116](https://swcregistry.io/docs/SWC-116)\n"
  },
  {
    "path": "docs/development-recommendations/solidity-specific/tx-origin.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nNever use `tx.origin` for authorization, another contract can have a method which will call your\ncontract (where the user has some funds for instance) and your contract will authorize that\ntransaction as your address is in `tx.origin`.\n\n```sol\ncontract MyContract {\n\n    address owner;\n\n    function MyContract() public {\n        owner = msg.sender;\n    }\n\n    function sendTo(address receiver, uint amount) public {\n        require(tx.origin == owner);\n        (bool success, ) = receiver.call.value(amount)(\"\");\n        require(success);\n    }\n\n}\n\ncontract AttackingContract {\n\n    MyContract myContract;\n    address attacker;\n\n    function AttackingContract(address myContractAddress) public {\n        myContract = MyContract(myContractAddress);\n        attacker = msg.sender;\n    }\n\n    function() public {\n        myContract.sendTo(attacker, msg.sender.balance);\n    }\n\n}\n```\n\nYou should use `msg.sender` for authorization (if another contract calls your contract `msg.sender`\nwill be the address of the contract and not the address of the user who called the contract).\n\nYou can read more about it here:\n[Solidity docs](https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin)\n\n!!! Warning\n    Besides the issue with authorization, there is a chance that `tx.origin` will be\n    removed from the Ethereum protocol in the future, so code that uses `tx.origin` won't be compatible\n    with future releases\n    [Vitalik: 'Do NOT assume that tx.origin will continue to be usable or meaningful.'](https://ethereum.stackexchange.com/questions/196/how-do-i-make-my-dapp-serenity-proof/200#200)\n\n    It's also worth mentioning that by using `tx.origin` you're limiting interoperability between\n    contracts because the contract that uses tx.origin cannot be used by another contract as a contract\n    can't be the `tx.origin`.\n\n    See [SWC-115](https://swcregistry.io/docs/SWC-115)\n"
  },
  {
    "path": "docs/development-recommendations/solidity-specific/visibility.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nExplicitly label the visibility of functions and state variables. Functions can be specified as\nbeing `external`, `public`, `internal` or `private`. Please understand the differences between\nthem, for example, `external` may be sufficient instead of `public`. For state variables,\n`external` is not possible. Labeling the visibility explicitly will make it easier to catch\nincorrect assumptions about who can call the function or access the variable.\n\n- `External` functions are part of the contract interface. An external function `f` cannot be\n  called internally (i.e. `f()` does not work, but `this.f()` works). External functions are\n  sometimes more efficient when they receive large arrays of data.\n- `Public` functions are part of the contract interface and can be either called internally or via\n  messages. For public state variables, an automatic getter function (see below) is generated.\n- `Internal` functions and state variables can only be accessed internally, without using `this`.\n- `Private` functions and state variables are only visible for the contract they\n  are defined in and not in derived contracts. **Note**: [Everything inside a\n  contract is visible to all observers external to the\n  blockchain](https://solidity.readthedocs.io/en/develop/contracts.html?#visibility-and-getters),\n  even `Private` variables.\n\n```sol\n// bad\nuint x; // the default is internal for state variables, but it should be made explicit\nfunction buy() { // the default is public\n    // public code\n}\n\n// good\nuint private y;\nfunction buy() external {\n    // only callable externally or using this.buy()\n}\n\nfunction utility() public {\n    // callable externally, as well as internally: changing this code requires thinking about both cases.\n}\n\nfunction internalAction() internal {\n    // internal code\n}\n```\n\nSee [SWC-100](https://swcregistry.io/docs/SWC-100) and\n[SWC-108](https://swcregistry.io/docs/SWC-108)\n"
  },
  {
    "path": "docs/development-recommendations/token-specific/contract-address.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nConsider also preventing the transfer of tokens to the same address of the smart contract.\n\nAn example of the potential for loss by leaving this open is the\n[EOS token smart contract](https://etherscan.io/address/0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0)\nwhere more than 90,000 tokens are stuck at the contract address.\n\n### Example\n\nAn example of implementing both the above recommendations would be to create the following\nmodifier; validating that the \"to\" address is neither 0x0 nor the smart contract's own address:\n\n```sol\n    modifier validDestination( address to ) {\n        require(to != address(0x0));\n        require(to != address(this) );\n        _;\n    }\n```\n\nThe modifier should then be applied to the \"transfer\" and \"transferFrom\" methods:\n\n```sol\n    function transfer(address _to, uint _value)\n        validDestination(_to)\n        returns (bool) \n    {\n        (... your logic ...)\n    }\n\n    function transferFrom(address _from, address _to, uint _value)\n        validDestination(_to)\n        returns (bool) \n    {\n        (... your logic ...)\n    }\n```\n"
  },
  {
    "path": "docs/development-recommendations/token-specific/frontrunning.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nThe EIP-20 token's `approve()` function creates the potential for an approved spender to spend more\nthan the intended amount. A\n[front running attack](../../attacks/frontrunning.md) can be\nused, enabling an approved spender to call `transferFrom()` both before and after the call to\n`approve()` is processed. More details are available on the\n[EIP](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#approve), and in\n[this document](https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/edit).\n"
  },
  {
    "path": "docs/development-recommendations/token-specific/standardization.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nGenerally speaking, smart contracts of tokens should follow an accepted and stable standard.\n\nExamples of currently accepted standards include:\n\n- [EIP20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md)\n- [EIP721](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md) (non-fungible token)\n- More at [eips.ethereum.org](https://eips.ethereum.org/erc#final)\n"
  },
  {
    "path": "docs/development-recommendations/token-specific/zero-address.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nAt the time of writing, the \"zero\" address\n([0x0000000000000000000000000000000000000000](https://etherscan.io/address/0x0000000000000000000000000000000000000000))\nholds tokens with a value of more than 80$ million.\n"
  },
  {
    "path": "docs/general-philosophy/blockchain-properties.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nWhile much of your programming experience will be relevant to Ethereum programming, there are some\npitfalls to be aware of.\n\n- Be extremely careful about external contract calls, which may execute malicious code and change\n  control flow.\n- Understand that your public functions are public, and may be called maliciously and in any order.\n  The private data in smart contracts is also viewable by anyone.\n- Keep gas costs and the block gas limit in mind.\n- Be aware that timestamps are imprecise on a blockchain, miners can influence the time of\n  execution of a transaction within a margin of several seconds.\n- Randomness is non-trivial on blockchain, most approaches to random number generation are gameable\n  on a blockchain.\n"
  },
  {
    "path": "docs/general-philosophy/index.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nEthereum and complex blockchain programs are new and highly experimental. Therefore, you should\nexpect constant changes in the security landscape, as new bugs and security risks are discovered,\nand new best practices are developed. Following the security practices in this document is\ntherefore only the beginning of the security work you will need to do as a smart contract\ndeveloper.\n\nSmart contract programming requires a different engineering mindset than you may be used to. The\ncost of failure can be high, and change can be difficult, making it in some ways more similar to\nhardware programming or financial services programming than web or mobile development. It is\ntherefore not enough to defend against known vulnerabilities. Instead, you will need to learn a new\nphilosophy of development:\n"
  },
  {
    "path": "docs/general-philosophy/prepare-for-failure.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nAny non-trivial contract will have errors in it. Your code must, therefore, be able to respond to\nbugs and vulnerabilities gracefully.\n\n- Pause the contract when things are going wrong ('circuit breaker')\n- Manage the amount of money at risk (rate limiting, maximum usage)\n- Have an effective upgrade path for bugfixes and improvements\n"
  },
  {
    "path": "docs/general-philosophy/rollout.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nIt is always better to catch bugs before a full production release.\n\n- Test contracts thoroughly, and add tests whenever new attack vectors are discovered\n- Provide [bug bounties](../bug-bounty-programs.md) starting from alpha testnet\n  releases\n- Rollout in phases, with increasing usage and testing in each phase\n"
  },
  {
    "path": "docs/general-philosophy/simplicity-vs-complexity.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nThere are multiple fundamental tradeoffs to consider when assessing the structure and security of a\nsmart contract system. The general recommendation for any smart contract system is to identify the\nproper balance for these fundamental tradeoffs.\n\nAn ideal smart contract system from a software engineering bias is modular, reuses code instead of\nduplicating it, and supports upgradeable components. An ideal smart contract system from a secure\narchitecture bias may share this mindset, especially in the case of more complex smart contract\nsystems.\n\nHowever, there are important exceptions where security and software engineering best practices may\nnot be aligned. In each case, the proper balance is obtained by identifying the optimal mix of\nproperties along contract system dimensions such as:\n\n- Rigid versus Upgradeable\n- Monolithic versus Modular\n- Duplication versus Reuse\n\n### Rigid versus Upgradeable\n\nWhile multiple resources, including this one, emphasize malleability characteristics such as\nKillable, Upgradeable or Modifiable patterns there is a *fundamental tradeoff* between malleability\nand security.\n\nMalleability patterns by definition add complexity and potential attack surfaces. Simplicity is\nparticularly effective over complexity in cases where the smart contract system performs a very\nlimited set of functionality for a pre-defined limited period of time, for example, a\ngovernance-free finite-time-frame token-sale contract system.\n\n### Monolithic versus Modular\n\nA monolithic self-contained contract keeps all knowledge locally identifiable and readable. While\nthere are few smart contract systems held in high regard that exist as monoliths, there is an\nargument to be made for extreme locality of data and flow - for example, in the case of optimizing\ncode review efficiency.\n\nAs with the other tradeoffs considered here, security best practices trend away from software\nengineering best practices in simple short-lived contracts and trend toward software engineering\nbest practices in the case of more complex perpetual contract systems.\n\n### Duplication versus Reuse\n\nA smart contract system from a software engineering perspective wishes to maximize reuse where\nreasonable. There are many ways to reuse contract code in Solidity. Using proven\npreviously-deployed contracts *which you own* is generally the safest manner to achieve code reuse.\n\nDuplication is frequently relied upon in cases where self-owned previously-deployed contracts are\nnot available. Efforts such as\n[OpenZeppelin's Solidity Library](https://github.com/OpenZeppelin/openzeppelin-contracts) seek to\nprovide patterns such that secure code can be re-used without duplication. Any contract security\nanalysis must include any re-used code that has not previously established a level of trust\ncommensurate with the funds at risk in the target smart contract system.\n"
  },
  {
    "path": "docs/general-philosophy/simplicity.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nComplexity increases the likelihood of errors.\n\n- Ensure the contract logic is simple\n- Modularize code to keep contracts and functions small\n- Use already-written tools or code where possible (eg. don't roll your own random number\n  generator)\n- Prefer clarity to performance whenever possible\n- Only use the blockchain for the parts of your system that require decentralization\n"
  },
  {
    "path": "docs/general-philosophy/stay-up-to-date.md",
    "content": "!!! tip\n\n    For comprehensive insights into secure development practices, consider visiting the [Development Recommendations](https://scsfg.io/developers/) section of the Smart Contract Security Field Guide. This resource provides in-depth articles to guide you in developing robust and secure smart contracts.\n\nKeep track of new security developments.\n\n- Check your contracts for any new bug as soon as it is discovered\n- Upgrade to the latest version of any tool or library as soon as possible\n- Adopt new security techniques that appear useful\n"
  },
  {
    "path": "docs/index.md",
    "content": "# Ethereum Smart Contract Security Best Practices\n\n!!! tip\n\n    Thank you for visiting the Smart Contract Security Best Practices. Please note that this resource is no longer actively maintained. Instead, we recommend visiting the [Smart Contract Security Field Guide](https://scsfg.io/). The Smart Contract Security Field Guide is regularly updated and curated by the same security engineer who previously contributed to the Best Practices guide.\n\nThis document provides a baseline knowledge of security considerations for intermediate Solidity\nprogrammers. It is maintained by [ConsenSys Diligence](https://consensys.net/diligence/), with\ncontributions from our friends in the broader Ethereum community.\n\nOur amazing community has also provided translations in\n[Chinese](https://github.com/ConsenSys/smart-contract-best-practices/blob/master/README-zh.md) and\n[Vietnamese](https://github.com/ConsenSys/smart-contract-best-practices/blob/master/README-vi.md).\n\n## Where to start?\n\n- [General Philosophy](./general-philosophy/index.md) describes the smart contract security mindset\n- [Development Recommendations](./development-recommendations/index.md) contains examples of good code patterns\n- [Known Attacks](./attacks/index.md) describes the different classes of vulnerabilities to avoid\n- [Security Tools](./security-tools/index.md) lists tools for improving code quality, and detecting\n  vulnerabilities\n- [Bug Bounties](./bug-bounty-programs.md) List of bug bounties in the ecosystem.\n\n## Contributions are welcome!\n\nFeel free to submit a pull request, with anything from small fixes, to full new sections. If you\nare writing new content, please reference the [contributing](./about/index.md) page for\nguidance on style.\n\nSee the [issues](https://github.com/ConsenSys/smart-contract-best-practices/issues) for topics that\nneed to be covered or updated.\n"
  },
  {
    "path": "docs/security-tools/classification.md",
    "content": "- [SWC-registry](https://github.com/SmartContractSecurity/SWC-registry/) - SWC definitions and a\n  large repository of crafted and real-world samples of vulnerable smart contracts.\n- [SWC Pages](https://smartcontractsecurity.github.io/SWC-registry/) - The SWC-registry repo\n  published on Github Pages"
  },
  {
    "path": "docs/security-tools/disassemblers.md",
    "content": "**Disassemblers**\n\nTools that translate smart contract bytecode into opcodes or EVM assembly.\n\n- [Ethersplay](https://github.com/crytic/ethersplay) - Binary Ninja plugin which enables an EVM disassembler and related analysis tools. \n- [Pyevmasm](https://github.com/crytic/pyevmasm) - Assembler and disassembler library for the Ethereum Virtual Machine (EVM). It includes a commandline utility and a Python API.\n- [IDA-EVM](https://github.com/crytic/ida-evm) - IDA Processor Module for the Ethereum Virtual Machine (EVM).\n- [Ethereum DASM](https://github.com/tintinweb/ethereum-dasm) - EVM bytecode disassembler with function signature lookup plus static and dynamic analysis.\n\n**Decompilers**\n\nAs above but translated into more readable Solidity-like code.\n\n- [JEB Ethereum Smart Contract Decompiler](https://www.pnfsoftware.com/blog/ethereum-smart-contract-decompiler/) - JEB decompiler plugin for Ethereum Smart Contracts\n- [Online Solidity Decompiler](https://ethervm.io/decompile) - Online tool that decompiles Ethereum contract bytecode into more readable Solidity-like code, allowing for better understanding of opaque/unverified contracts.\n- [Dedaub Decompiler](https://library.dedaub.com/decompile) - EVM bytecode decompiler and disassembler hybrid with 3 address code view deployed on a website.\n"
  },
  {
    "path": "docs/security-tools/index.css",
    "content": ".md-typeset__table {\n    width: 818px;\n    max-width: 100%;\n}\n\n@media only screen and (min-width: 1600px) {\n    .md-typeset__table {\n        width: 900px;\n    }\n}"
  },
  {
    "path": "docs/security-tools/index.md",
    "content": "<link href=\"./index.css\" rel=\"stylesheet\"></link>\nThis section is about tools that can detect vulnerabilities or help developers maintain a high\ncode quality to reduce the likelihood and impact of vulnerabilities.\n\n| Category                                                        | Description                                                                                         |\n| --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |\n| [Visualization](./visualization.md)                             | These tools are aimed at visualizing, EVM bytecode, smart contracts, and their control flow graphs. |\n| [Static and Dynamic Analysis](./static-and-dynamic-analysis.md) | Tools that employ various means of program analysis to find vulnabilities and weaknesses.           |\n| [Classification](./classification.md)                           | Resources attempting to classify vulnerabilities and weaknesses in smart contracts.                 |\n| [Testing](./testing.md)                                         | Tools for running, measuring, and managing smart contract related tests.                            |\n| [Linters and Formatters](./linters-and-formatters.md)           | Any tools that highlight code smells and make smart contract code adhere to format standards.       |\n| [Disassemblers and Decompilers](./disassemblers.md)             | Tools that translate smart contract bytecode into opcodes and solidity code.                        |\n| [Formal and Runtime Verification](./verification.md)            | Tools employing verification techniques to detect behaviour satisfying or vioating invariants.      |\n\n<div class=\"security-tools-wrapper\">\n    <div class=\"inner-wrapper\">\n        <div class=\"left\">\n            <div>\n                <p class=\"title\">The Diligence Security Tooling Guide</p>\n                <p class=\"sub-title\">Download a free copy of the Diligence Security Tooling Guide to discover the top tools in Web3 you can use at any phase of your smart contract development to test and improve security.</p>\n            </div>\n            <a href=\"https://consensys.net/diligence/resources/security-tooling-guide?utm_source=github&utm_medium=devcommunity&utm_campaign=2022_Nov_diligence-security-tooling-guide_content_content\" target=\"_blank\">Download guide</a>\n        </div>\n        <div class=\"right\">\n            <img src=\"../img/security-tools.png\" alt=\"The Diligence Security Tooling Guide\" />\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "docs/security-tools/linters-and-formatters.md",
    "content": "Linters improve code quality by enforcing rules for style and composition, making code easier to\nread and review.\n\n- [Ethlint](https://github.com/duaraghav8/Ethlint) - Yet another Solidity linting.\n- [Solhint](https://github.com/protofire/solhint) - A linter for Solidity that provides both\n  Security and Style Guide validations.\n- [Prettier](https://prettier.io/) +\n  [Solidity Plugin](https://github.com/prettier-solidity/prettier-plugin-solidity) - Prettier\n  enforces basic style conventions in your code.\n"
  },
  {
    "path": "docs/security-tools/static-and-dynamic-analysis.md",
    "content": "- [MythX](https://mythx.io) - MythX is a professional-grade cloud service that uses symbolic\n  analysis and input fuzzing to\n  [detect common security bugs](https://medium.com/consensys-diligence/detecting-the-top-4-critical-smart-contract-vulnerabilities-with-mythx-9c568d7db7a6)\n  and\n  [verify the correctness of smart contract code](https://medium.com/coinmonks/advanced-smart-contract-security-verification-in-remix-9630b43695e5).\n  Using MythX requires an API key from [mythx.io](https://mythx.io).\n- [Mythril](https://github.com/ConsenSys/mythril) - The Swiss army knife for smart contract\n  security.\n- [Slither](https://github.com/trailofbits/slither) - Static analysis framework with detectors for\n  many common Solidity issues. It has taint and value tracking capabilities and is written in\n  Python.\n- [Contract-Library](https://contract-library.com) - Decompiler and security analysis tool for all\n  deployed contracts.\n- [MadMax](https://github.com/nevillegrech/MadMax) - Static analysis tool for gas DoS\n  vulnerabilities.\n- [Gigahorse](https://github.com/nevillegrech/gigahorse-toolchain) - Fast binary lifter and program\n  analysis framework written in Datalog.\n- [Echidna](https://github.com/trailofbits/echidna) - The only available fuzzer for Ethereum\n  software. Uses property testing to generate malicious inputs that break smart contracts.\n- [Manticore](https://github.com/trailofbits/manticore) - Dynamic binary analysis tool with\n  [EVM support](https://asciinema.org/a/haJU2cl0R0Q3jB9wd733LVosL).\n- [Oyente](https://github.com/melonproject/oyente) - Analyze Ethereum code to find common\n  vulnerabilities, based on this [paper](http://www.comp.nus.edu.sg/~loiluu/papers/oyente.pdf).\n- [Securify](https://github.com/eth-sri/securify2) - Fully automated online static analyzer for\n  smart contracts, providing a security report based on vulnerability patterns.\n- [SmartCheck](https://smartdec.net) - Static analysis of Solidity source code for security\n  vulnerabilities and best practices.\n- [Octopus](https://github.com/pventuzelo/octopus) - Security Analysis tool for Blockchain Smart\n  Contracts with support of EVM and (e)WASM.\n- [sFuzz](https://sfuzz.github.io/) - Efficient fuzzer inspired from AFL to find common\n  vulnerabilities.\n- [Vertigo](https://github.com/JoranHonig/vertigo) - Mutation Testing for Ethereum Smart Contracts.\n- [SolidityScan](https://solidityscan.com/) - Vulnerability Scanner for Solidity Smart Contracts with over 200+ exploit and CVEs, misconfigurations, and gas optimization modules.\n"
  },
  {
    "path": "docs/security-tools/testing.md",
    "content": "- [solidity-coverage](https://github.com/sc-forks/solidity-coverage) - Code coverage for Solidity\n  testing.\n- [solidity-shell](https://github.com/tintinweb/solidity-shell) - An interactive Solidity shell with lightweight session recording and remote compiler support.\n- [chisel](https://github.com/foundry-rs/foundry/tree/master/chisel) - Chisel is a fast, utilitarian, and verbose solidity REPL. It is heavily inspired by the incredible work done in soli and solidity-shell!\n- [soli](https://github.com/jpopesculian/soli) - Solidity REPL\n"
  },
  {
    "path": "docs/security-tools/verification.md",
    "content": "- [Scribble](https://consensys.net/diligence/scribble/) - Runtime verification tool for Solidity that enables you to write specifications to test, fuzz or symbolically execute contracts (e.g using Mythril or the MythX service) to check if your properties can be violated.\n- [KEVM](https://github.com/kframework/evm-semantics) - Formal verification framework that models EVM semantics.\n- [Certora Prover](https://certora.atlassian.net/wiki/spaces/CPD/pages) - Formal verification tool that checks if a smart contract satisfies a set of rules written in CVL (Certora Verification Language).\n"
  },
  {
    "path": "docs/security-tools/visualization.md",
    "content": "- [Solidity Visual Developer](https://marketplace.visualstudio.com/items?itemName=tintinweb.solidity-visual-auditor)\n  \\- This extension contributes security centric syntax and semantic highlighting, a detailed class\n  outline and advanced Solidity code insights to Visual Studio Code\n- [Sūrya](https://github.com/ConsenSys/surya) - Utility tool for smart contract systems, offering a\n  number of visual outputs and information about the contracts' structure. Also supports querying\n  the function call graph.\n- [Solgraph](https://github.com/raineorshine/solgraph) - Generates a DOT graph that visualizes\n  function control flow of a Solidity contract and highlights potential security vulnerabilities.\n- [EVM Lab](https://github.com/ethereum/evmlab) - Rich tool package to interact with the EVM.\n  Includes a VM, Etherchain API, and a trace-viewer.\n- [ethereum-graph-debugger](https://github.com/fergarrui/ethereum-graph-debugger) - A graphical EVM\n  debugger. Displays the entire program control flow graph.\n- [Piet](https://github.com/slockit/piet) - Web application helping understand smart contract\n  architectures. Offers graphical representation and inspection of smart contracts as well as a\n  markdown documentation generator.\n"
  },
  {
    "path": "docs/stylesheets/extra.css",
    "content": "@font-face {\n    font-family: 'Graphik';\n    src: url('./fonts/Graphik-Bold-Web.woff2') format('woff2'),\n        url('./fonts/Graphik-Bold-Web.woff') format('woff');\n    font-weight: 700;\n}\n\n@font-face {\n    font-family: 'Graphik';\n    src: url('fonts/Graphik-Semibold-Web.woff2') format('woff2'),\n        url('fonts/Graphik-Semibold-Web.woff') format('woff');\n    font-weight: 600;\n}\n\n@font-face {\n    font-family: 'Graphik';\n    src: url('fonts/Graphik-Regular-Web.woff2') format('woff2'),\n        url('fonts/Graphik-Regular-Web.woff') format('woff');\n    font-weight: 400;\n}\n\n.md-header {\n    background-color: #1F507A;\n}\n\n.md-footer-diligence {\n    float: right;\n    color: hsla(0, 0%, 100%, .3);\n    margin-right: 1.3rem;\n    font-size: 1.28rem;\n    padding: 0.8rem 0;\n}\n\n.md-footer-diligence a img {\n    height: auto;\n    width: 22px;\n    vertical-align: text-bottom;\n}\n\n.md-footer-social svg {\n    -webkit-filter: invert(100%);\n    /* safari 6.0 - 9.0 */\n    filter: invert(100%);\n    margin-right: 1rem;\n}\n\n.security-tools-wrapper .inner-wrapper {\n    font-family: 'Graphik';\n    color: #FFF;\n    padding: 37px 22px 28px 31px;\n    background-image: url(\"../img/bg-security-tools.png\");\n    gap: 40px;\n    display: flex;\n    border-radius: 8px;\n    max-width: 786px;\n}\n\n@media only screen and (max-width: 767px) { \n    .security-tools-wrapper .inner-wrapper {\n        flex-direction: column-reverse;\n    }\n}\n\n@media only screen and (min-width: 1600px) {\n    .security-tools-wrapper .inner-wrapper {\n        max-width: 864.8px;\n    }\n}\n\n.security-tools-wrapper .inner-wrapper .left {\n    display: flex;\n    flex-direction: column;\n    justify-content: space-between;\n}\n\n\n.security-tools-wrapper .inner-wrapper .left .title {\n    font-weight: 700;\n    font-size: 34px;\n    line-height: 120%;\n    margin-top: 0;\n    margin-bottom: 12px;\n    letter-spacing: -0.53px;\n}\n\n.security-tools-wrapper .inner-wrapper .left .sub-title {\n    font-size: 13px;\n    font-weight: 400;\n    line-height: 150%;\n    letter-spacing: 0.2px;\n    color: #BDBDBD;\n    margin-top: 12px;\n    margin-bottom: 30px;\n}\n\n.security-tools-wrapper .inner-wrapper .left a {\n    text-transform: uppercase;\n    max-width: 159px;\n    color: #FFF;\n    font-size: 11px;\n    line-height: 12px;\n    font-weight: 600;\n    padding: 11.47px 27.5px;\n    background-color: #2C56DD;\n    border-radius: 2.7px;\n    transition: opacity 0.3s ease;\n}\n\n.security-tools-wrapper .inner-wrapper .left a:hover {\n    opacity: 0.8;\n}\n\n.security-tools-wrapper .inner-wrapper .right {\n    align-self: center;\n}"
  },
  {
    "path": "mkdocs.yml",
    "content": "# Refer to https://github.com/mkdocs/mkdocs/blob/master/mkdocs.yml for a working example\nsite_name: Ethereum Smart Contract Best Practices\nsite_url: https://consensys.github.io/smart-contract-best-practices/\nsite_description: Ethereum Smart Contract Security Best Practices\nsite_author: ConsenSys Diligence\nrepo_url: https://github.com/ConsenSys/smart-contract-best-practices\nrepo_name: Github\nremote_branch: gh-pages\nremote_name: origin\nstrict: true\n\nnav:\n  - Home: index.md\n  - General Philosophy:\n    - general-philosophy/index.md\n    - Prepare for Failure: general-philosophy/prepare-for-failure.md\n    - Stay up to Date: general-philosophy/stay-up-to-date.md\n    - Keep it Simple: general-philosophy/simplicity.md\n    - Rolling out: general-philosophy/rollout.md\n    - Blockchain Properties: general-philosophy/blockchain-properties.md\n    - Simplicity vs. Complexity: general-philosophy/simplicity-vs-complexity.md\n  - Development Recommendations:\n    - development-recommendations/index.md\n    - General:\n      - External Calls: development-recommendations/general/external-calls.md\n      - Force-feeding Ether: development-recommendations/general/force-feeding.md\n      - Public on-chain Data: development-recommendations/general/public-data.md\n      - Unreliable Participants: development-recommendations/general/participants.md\n      - Negation of Signed Integers: development-recommendations/general/negative-int.md\n    - Precautions:\n      - General: development-recommendations/precautions/general.md\n      - Upgradeability: development-recommendations/precautions/upgradeability.md\n      - Circuit Breakers: development-recommendations/precautions/circuit-breakers.md\n      - Speed Bumps: development-recommendations/precautions/speed-bumps.md\n      - Rate Limiting: development-recommendations/precautions/rate-limiting.md\n      - Deployment: development-recommendations/precautions/deployment.md\n      - Safe Haven: development-recommendations/precautions/safe-haven.md\n    - Solidity-specific:\n      - Assert, Require, Revert: development-recommendations/solidity-specific/assert-require-revert.md\n      - Modifiers as Guards: development-recommendations/solidity-specific/modifiers-as-guards.md\n      - Integer Division: development-recommendations/solidity-specific/integer-division.md\n      - Abstract vs Interfaces: development-recommendations/solidity-specific/abstract-vs-interfaces.md\n      - Fallback Functions: development-recommendations/solidity-specific/fallback-functions.md\n      - Payability: development-recommendations/solidity-specific/payability.md\n      - Visibility: development-recommendations/solidity-specific/visibility.md\n      - Locking Pragmas: development-recommendations/solidity-specific/locking-pragmas.md\n      - Event Monitoring: development-recommendations/solidity-specific/event-monitoring.md\n      - Shadowing: development-recommendations/solidity-specific/shadowing.md\n      - tx.origin: development-recommendations/solidity-specific/tx-origin.md\n      - Timestamp Dependence: development-recommendations/solidity-specific/timestamp-dependence.md\n      - Complex Inheritance: development-recommendations/solidity-specific/complex-inheritance.md\n      - Interface Types: development-recommendations/solidity-specific/interface-types.md\n      - EXTCODESIZE Checks: development-recommendations/solidity-specific/extcodesize-checks.md\n    - Token-specific:\n      - Standardization: development-recommendations/token-specific/standardization.md\n      - Frontrunning: development-recommendations/token-specific/frontrunning.md\n      - Zero Address: development-recommendations/token-specific/zero-address.md\n      - Contract Address: development-recommendations/token-specific/contract-address.md\n    - Documentation:\n      - General: development-recommendations/documentation/general.md\n      - Specification: development-recommendations/documentation/specification.md\n      - Status: development-recommendations/documentation/status.md\n      - Procedures: development-recommendations/documentation/procedures.md\n      - Known Issues: development-recommendations/documentation/known-issues.md\n      - History: development-recommendations/documentation/history.md\n      - Contact: development-recommendations/documentation/contact.md\n    - Deprecated:\n      - Division by Zero: development-recommendations/deprecated/division-by-zero.md\n      - Functions and Events: development-recommendations/deprecated/functions-and-events.md\n      - Constructor Naming: development-recommendations/deprecated/constructor-naming.md\n  - Attacks:\n    - attacks/index.md\n    - Reentrancy: attacks/reentrancy.md\n    - Oracle Manipulation: attacks/oracle-manipulation.md\n    - Frontrunning: attacks/frontrunning.md\n    - Timestamp Dependence: attacks/timestamp-dependence.md\n    - Insecure Arithmetic: attacks/insecure-arithmetic.md\n    - Denial of Service: attacks/denial-of-service.md\n    - Griefing: attacks/griefing.md\n    - Force Feeding: attacks/force-feeding.md\n    - Deprecated/Historical: attacks/deprecated.md\n    - More: attacks/more.md\n  - Security Tools:\n    - security-tools/index.md\n    - Visualization: security-tools/visualization.md\n    - Static and Dynamic Analysis: security-tools/static-and-dynamic-analysis.md\n    - Classification: security-tools/classification.md\n    - Testing: security-tools/testing.md\n    - Linters and Formatters: security-tools/linters-and-formatters.md\n  - Bug Bounty Programs: bug-bounty-programs.md\n  - About:\n    - about/index.md\n    - License: about/license.md\n\ntheme:\n  name: 'material'\n  custom_dir: 'custom'\n  logo: 'assets/images/CDili.png'\n  favicon: 'assets/images/CDili_black.png'\n  language: en\n  features:\n    - toc.integrate\n    - navigation.instant\n    - header.autohide\n    # - navigation.sections\n    - navigation.top\n    - navigation.tabs\n    - navigation.tabs.sticky\n    - navigation.indexes\n  palette: \n    - scheme: default\n      primary: black\n      accent: deep-purple\n      toggle:\n        icon: material/lightbulb\n        name: Switch to light mode\n    - scheme: slate\n      primary: black\n      accent: cyan\n      toggle:\n        icon: material/lightbulb-outline\n        name: Switch to dark mode\n\nextra_css:\n  - 'stylesheets/extra.css'\n\nextra:\n  social:\n    - icon: fontawesome/solid/shield-alt\n      link: https://consensys.net/diligence/blog/\n    - icon: fontawesome/brands/github\n      link: https://github.com/ConsenSys/\n    - icon: fontawesome/brands/twitter\n      link: https://twitter.com/ConsenSysAudits\n    - icon: fontawesome/brands/medium\n      link: https://medium.com/consensys-diligence\n    - icon: fontawesome/brands/youtube\n      link: https://www.youtube.com/channel/UCkoGLA5DUdXO4Qfo_9RDjIA/playlists\n  analytics:\n    provider: google\n    property: G-VYGQ8GTH45\n\nmarkdown_extensions:\n  - toc:\n      permalink: true\n  - pymdownx.arithmatex:\n      generic: true\n  - pymdownx.betterem:\n      smart_enable: all\n  - pymdownx.critic:\n      mode: view\n  - pymdownx.tasklist:\n      custom_checkbox: true\n  - admonition\n  - def_list\n  - footnotes\n  - meta\n  - pymdownx.highlight\n  - pymdownx.inlinehilite\n  - pymdownx.caret\n  - pymdownx.details\n  - pymdownx.magiclink\n  - pymdownx.mark\n  - pymdownx.smartsymbols\n  - pymdownx.superfences\n  - pymdownx.tilde\n  - markdown_include.include\n"
  },
  {
    "path": "requirements.txt",
    "content": "mkdocs\nmkdocs-material\npygments-lexer-solidity\npymdown-extensions\nmarkdown-include\nlinkcheckmd\nrequests"
  }
]