Slither unprotected-upgradeable-contract 探測器
我一直在我的項目中使用可升級的 Openzeppelin 合約,今天我決定執行滑行工具來檢查它的執行情況。嗯……顯然不是很好。但我不明白真正的問題在哪裡(或者是否是誤報),所以我需要你的幫助。
探測器說:
CalculatorUpgradeable (contracts/Calculator.sol#13-59) is an upgradeable contract that does not protect its initiliaze functions: CalculatorUpgradeable.initialize() (contracts/Calculator.sol#31-33). Anyone can delete the contract with: UUPSUpgradeable.upgradeTo(address) (node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol#72-75)UUPSUpgradeable.upgradeToAndCall(address,bytes) (node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol#85-88)
“不保護其初始化功能”是什麼意思?初始化函式有 onlyOwner 修飾符。
在文件中,他們建議添加一個建構子以確保不能在邏輯合約上呼叫“初始化”。對不起,但我沒明白:(
以下是此檢測器擷取的合約程式碼:
// SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.9.0; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; contract CalculatorUpgradeable is Initializable, OwnableUpgradeable, UUPSUpgradeable { function initialize() external initializer onlyOwner { __Ownable_init(); } function calcPercentage(uint256 amount, uint256 percentage) external pure returns (uint256) { return (amount * percentage * 100) / 10000; } function _authorizeUpgrade(address newImplementation) internal override onlyOwner {} }
非常感謝您的任何澄清,
基於此,它似乎是誤報https://github.com/crytic/slither/pull/1046
它應該很快修復。
順便說一句,你的智能合約有問題
function initialize() external initializer onlyOwner { __Ownable_init(); }
它應該被呼叫,
onlyOwner
但此時它owner
是address(0)
不可能呼叫函式initialize()
,因為你不是所有者。
根據貢獻者
0xalpharush
在本期https://github.com/crytic/slither/issues/1136中的回答,靜音此 FP 的一種解決方案是將修飾符添加onlyProxy
到初始化函式中。修飾符
onlyProxy
在抽象合約中定義,UUPSUpgradeable
它檢查sinalized函式的執行是否通過delegatecall呼叫執行,並且執行上下文是具有指向實現合約的實現(如ERC1967中定義)的代理合約。