16 Tháng mười hai, 2021
Giới thiệu
Sản phẩm 1inch nhóm đã yêu cầu chúng tôi xem xét và kiểm tra Giao thức đặt hàng giới hạn hợp đồng thông minh v2. Chúng tôi đã xem xét mã và bây giờ công bố kết quả của mình.
Phạm vi
Chúng tôi đã kiểm toán cam kết 4d94eea25e4dac6271bfd703096a5c4a4d899b4a
của 1inch/limit-order-protocol
kho. Trong phạm vi là các hợp đồng sau:
– OrderMixin.sol
– OrderRFQMixin.sol
– PredicateHelper.sol
– RevertReasonParser.sol
– Permitable.sol
– ChainlinkCalculator.sol
– ArgumentsDecoder.sol
– AmountCalculator.sol
– NonceManager.sol
– LimitOrderProtocol.sol
– ImmutableOwner.sol
– InteractiveNotificationReceiver.sol
– AggregatorInterface.sol
– IDaiLikePermit.sol
Tất cả các tệp và thư mục dự án khác (bao gồm cả các bài kiểm tra), cùng với các dự án và phụ thuộc bên ngoài, lý thuyết trò chơi và thiết kế khuyến khích, cũng bị loại khỏi phạm vi kiểm tra này. Các phần phụ thuộc của mã và hợp đồng bên ngoài được cho là hoạt động như các dịch vụ được ghi lại và phụ trợ do 1inch cung cấp được cho là hoạt động vì lợi ích tốt nhất của giao thức.
Sức khỏe tổng quát
Nhìn chung, chúng tôi nhận thấy cơ sở mã của dự án có thể đọc được và được tổ chức tốt, mặc dù nó có thể được hưởng lợi từ tài liệu mở rộng hơn, đặc biệt là xung quanh các khối mã hợp ngữ, các trường hợp biên của giao thức, nội dung/vị ngữ/tài nguyên bên ngoài sẽ được sử dụng, trách nhiệm/hạn chế của dịch vụ phụ trợ được cung cấp và tương tác giữa các tác nhân. Dự án đã nỗ lực rất nhiều để thực hiện các hành động tiết kiệm nhiên liệu, đôi khi thậm chí có nguy cơ khiến mã trở nên khó giải thích hơn; chúng tôi nêu ra các vấn đề liên quan đến điều đó dưới đây. Trong suốt quá trình kiểm tra, nhóm 1inch luôn sẵn sàng, phản ứng nhanh và rất dễ làm việc cùng.
Tổng quan hệ thống
Giao thức đặt hàng giới hạn cho phép đặt hàng makers
để ký các đơn đặt hàng ngoài chuỗi để hoán đổi mã thông báo. Giao thức sau đó tạo điều kiện thuận lợi cho việc thực hiện các đơn đặt hàng đã ký trước đó theo đơn đặt hàng takers
. Đơn đặt hàng có khả năng mở rộng cao và có thể gọi tĩnh các hợp đồng bên ngoài tại một số điểm trong suốt quá trình thực hiện đơn hàng. Khả năng mở rộng này mang lại tiện ích cho giao thức, nhưng nó tăng thêm cả độ phức tạp và bề mặt tấn công lớn hơn cho chính các lệnh.
Điều quan trọng cần lưu ý là không có lưu trữ chi tiết đơn hàng trên chuỗi. Trạng thái điền hoặc hủy của đơn hàng chỉ được theo dõi thông qua hàm băm đơn hàng. Điều này đòi hỏi các đơn đặt hàng phải được chia sẻ ngang hàng hoặc thông qua một bên tập trung. Trong trường hợp này, nhóm 1inch dự định đóng vai trò là bên tập trung, tổng hợp các đơn đặt hàng đã ký và sử dụng các đơn đặt hàng đó làm nguồn thanh khoản cho các giao thức khác của họ. Đơn đặt hàng sẽ được xuất bản thông qua API riêng để người dùng có thể tương tác với chúng.
Sự tập trung hóa này mang lại cho nhóm 1inch quyền kiểm soát tối đa đối với những đơn hàng nào được xuất bản và thực hiện cuối cùng. Điều này cũng mang lại cho họ khả năng kiểm duyệt các đơn đặt hàng, có thể hữu ích trong trường hợp các đơn đặt hàng độc hại hoặc lừa đảo, nhưng cũng có thể bị lạm dụng và cho phép họ chạy trước bất kỳ người dùng nào khác trong trường hợp đơn đặt hàng có lợi bằng cách không hiển thị đơn hàng đó thông qua API.
Các vai trò đặc quyền
Mặc dù các hợp đồng mà vai trò được sử dụng nằm ngoài phạm vi, nhưng một vai trò đặc quyền đã được xác định. MỘT immutableOwner
được đặt thành người tạo hợp đồng proxy tại thời điểm xây dựng và được sử dụng để hạn chế quyền truy cập vào proxy external
chức năng.
Sự phụ thuộc bên ngoài và giả định về niềm tin
Thiết kế của giao thức này đòi hỏi các thành phần ngoài chuỗi và trên chuỗi, đồng thời mô hình kết hợp này có thể được sử dụng để giảm thiểu một số vectơ tấn công mà chúng tôi xác định trong báo cáo của mình, nhưng cái giá phải trả cho khả năng đó là sự phụ thuộc ngày càng tăng vào nhóm 1inch và cơ sở hạ tầng.
Ngoài ra, Giao thức đặt hàng giới hạn cung cấp các chức năng nhằm lấy giá từ các nhà tiên tri Chainlink. Chúng tôi cho rằng những lời tiên tri đó là trung thực, dễ tiếp cận và hoạt động bình thường.
Hơn nữa, do tính linh hoạt của đơn hàng, có một số điểm liên hệ với các hợp đồng bên ngoài không được xác thực. Điều này có nghĩa là người dùng độc hại có thể lạm dụng các lệnh gọi như vậy và mạo danh các vị từ, nội dung hoặc tiên tri bằng các hợp đồng độc hại để thực hiện các hành động trong quá trình thực hiện đơn hàng. Mặc dù dự án được bảo vệ ở một số khu vực chống lại sự quay trở lại, những vectơ như vậy có thể gây ra các cuộc tấn công từ chối dịch vụ hoặc các đơn đặt hàng thư rác không bị phát hiện. Nhóm 1inch biết rằng một số vấn đề nhất định có thể xuất hiện khi sử dụng các hợp đồng không quen thuộc cho giao thức và đã cho biết ý định của họ rằng chỉ những tài sản “blue chip” lớn mới được dự án hỗ trợ đầy đủ. Tuy nhiên, cần lưu ý rằng ngay cả với những tài sản phổ biến nhất, vẫn có những hành vi nội tại của mỗi tài sản có thể gây ra sự cố trên các giao thức không giải quyết chúng đúng cách, chẳng hạn như bị tính phí khi chuyển bằng USDT hoặc trả lại mã lỗi thay vì boolean thành công với cTokens.
Những phát hiện
Ở đây chúng tôi trình bày những phát hiện của chúng tôi.
Mức độ nghiêm trọng
Không có.
Mức độ nghiêm trọng cao
[H01] Dữ liệu không nhất quán được truyền vào _makeCall
Trong tạp chí OrderMixin
hợp đồng, _makeCall
chức năng được sử dụng để chuyển tài sản từ người nhận đến người sản xuất và sau đó từ người sản xuất đến người nhận. Trong lần chuyển giao sau, _makeCall
chức năng được chuyển sai lệnh makerAsset
là tham số cuối cùng, khi nào nó phải là thứ tự makerAssetData
.
Kết quả là, bất kỳ chức năng proxy nào dựa trên makerAssetData
lập luận sẽ tan vỡ.
Để nhất quán với lời kêu gọi trước đó tới _makeCall
và để hỗ trợ đầy đủ chức năng proxy, hãy cân nhắc việc cập nhật order.makerAsset
tham số để order.makerAssetData
.
Cập nhật: Cố định yêu cầu kéo # 57.
[H02] Lệnh riêng được điền một phần có thể được thực hiện bởi bất kỳ ai
Giao thức cho phép tạo ra các lệnh riêng tư và công cộng. Theo đơn đặt hàng riêng, chỉ allowedSender
địa chỉ do nhà sản xuất chỉ định trong quá trình tạo đơn hàng, có thể thực hiện đơn hàng.
Tuy nhiên, trong OrderMixin
hợp đồng, xác nhận cho allowedSender
địa chỉ có phạm vi không chính xác, nghĩa là nó chỉ được đánh giá bên trong logic xử lý lần thực hiện đơn hàng đầu tiên. Nếu một lệnh riêng được thực hiện một phần thì việc kiểm tra allowedSender
địa chỉ không thể truy cập được nữa và bất kỳ ai cũng có thể điền đơn đặt hàng.
Để làm rõ ý định xung quanh việc liệu bất kỳ người dùng nào có thể thực hiện các đơn đặt hàng riêng tư được thực hiện một phần hay không, hãy xem xét việc ghi lại lý do cho hành vi hiện tại hoặc xác thực allowedSender
địa chỉ nằm ngoài phạm vi của lần điền đầu tiên để đảm bảo rằng nó sẽ được xác thực mỗi khi thử điền.
Cập nhật: Cố định yêu cầu kéo # 58.
[H03] Nhà sản xuất độc hại có thể lợi dụng việc lấp đầy một phần để đánh cắp tài sản của người nhận
Đơn đặt hàng từ OrderMixin
hợp đồng có khả năng được thực hiện một phần. Để hỗ trợ thực hiện một phần, giao thức yêu cầu một cách tính toán cả hai mặt của giao dịch hoán đổi. Cả hai getMakerAmount
và getTakerAmount
các trường được xác định bởi người tạo đơn hàng cho mục đích chính xác này.
Khi điền đơn đặt hàng, người nhận phải cung cấp hoặc makingAmount
hoặc là takingAmount
những giá trị cũng như một thresholdAmount
giá trị. Có hai đường dẫn mã khác nhau có thể được thực hiện, dựa trên việc liệu makingAmount
hoặc là takingAmount
đã được cung cấp.
Đầu tiên là khi makingAmount
tham số được xác định. Nó có thể cắt bớt các makingAmount
giá trị và cả tính toán takingAmount
giá trị cho nó. Trong tình huống này, thresholdAmount
đảm bảo rằng takingAmount
giá trị được lấy là không lớn bất ngờ.
Điều thứ hai là khi takingAmount
tham số được xác định. Trong trường hợp như vậy, nó sẽ tính toán makingAmount
giá trị, có khả năng cắt ngắn nó và tính toán lại takingAmount
giá trị nếu điều đó xảy ra. Trong tình huống này, thresholdAmount
giá trị đảm bảo rằng makingAmount
giá trị trả về là không nhỏ bất ngờ.
Tồn tại hai phương thức khai thác, mỗi phương thức duy nhất dành cho một trong các đường dẫn mã đã đề cập trước đó. Các phương pháp khai thác này yêu cầu phần mềm độc hại getMakerAmount
và getTakerAmount
chức năng. Việc triển khai đơn giản các chức năng này sẽ có hành vi giống hệt với AmountCalculator
'S getMakerAmount
và getTakerAmount
nhưng với một công tắc được mã hóa cứng sẽ buộc chúng trả về giá trị do kẻ tấn công kiểm soát khi cần.
Mẫu khai thác đầu tiên, ít nghiêm trọng hơn liên quan đến đường dẫn mã đầu tiên trong đó makingAmount
giá trị được chỉ định theo thứ tự điền. Một nhà sản xuất độc hại sẽ đợi một lệnh điền chỉ định makingAmount
xuất hiện trong mempool để chạy trước nó. Họ sẽ rút hết giá trị ngoại trừ 1 từ phía nhà sản xuất và sau đó buộc _callGetTakerAmount
để trả lại số tiền được chỉ định trong người dùng thresholdAmount
giá trị (hoặc trợ cấp của họ nếu nó ít hơn). Khi giao dịch của người dùng cuối cùng được thực hiện, họ sẽ trao đổi toàn bộ thresholdAmount
giá trị của takerAsset
cho một đơn vị duy nhất makerAsset
. Việc khai thác này bị giới hạn bởi số lượng được cung cấp bởi thresholdAmount
giá trị hoặc số lượng của takerAsset
người dùng cho phép trên LimitOrderProtocol
hợp đồng.
Mẫu khai thác thứ hai, nghiêm trọng hơn liên quan đến đường dẫn mã thứ hai trong đó takingAmount
giá trị được chỉ định. Tương tự, nhà sản xuất độc hại sẽ đợi một lệnh điền được chỉ định một takingAmount
giá trị hiển thị trong mempool. Họ sẽ dẫn đầu giao dịch và buộc makingAmount
giá trị được trả lại bởi _callGetMakerAmount
chức năng cao hơn cả hai remainingMakerAmount
và thresholdAmount
. Họ cũng sẽ thiết lập takingAmount
giá trị trả về bởi _callGetTakerAmount
là số lượng của takerAsset
tài sản được phép trên LimitOrderProtocol
bởi người nhận. Khi giao dịch của người nhận được thực hiện, nó sẽ cắt ngắn makingAmount
giá trị và sau đó tính toán lại takingAmount
giá trị. Tuy nhiên, việc tính toán lại này không đảm bảo sẽ thấp hơn và trong trường hợp này sẽ khiến người thực hiện mất đi tất cả takerAsset
mà họ cho phép trong hợp đồng. Trong đường dẫn mã này, thresholdAmount
giá trị là đảm bảo rằng makingAmount
không quá thấp, vì vậy lấy đi tất cả của người nhận takerAsset
tài sản không được chọn. Số tiền bị mất được giới hạn bởi số tiền takerAsset
nội dung người dùng cho phép trên LimitOrderProtocol
hợp đồng.
Những hoạt động khai thác này không thể thực hiện được nếu không có các lệnh một phần và cụ thể hơn là các lệnh một phần có mã độc. getMakerAmount
và getTakerAmount
thực hiện.
Vấn đề chính của thresholdAmount
kiểm tra giá trị là nó chỉ bao gồm một mặt của trao đổi, nhưng mặt còn lại có thể được thao tác thông qua việc chạy trước. Không có gì đảm bảo rằng giá trị mà người nhận đề xuất ban đầu vẫn không thay đổi. Xem xét việc loại bỏ makingAmount
cắt bớt cả hai đường dẫn mã và hoàn nguyên nếu đơn hàng không thể hỗ trợ điền lớn như yêu cầu. Bằng cách làm này, thresholdAmount
có thể được sử dụng để hạn chế đầy đủ phía bên kia của trao đổi và tránh hành vi không mong muốn, ngay cả trong các đơn đặt hàng độc hại.
Cập nhật: Cố định yêu cầu kéo # 83.
Mức độ nghiêm trọng trung bình
[M01] Đối số tĩnh được truyền sau đối số động
Trong tạp chí OrderMixin
hợp đồng, getTakerAmount
và getMakerAmount
các trường byte được sử dụng làm đối số cho _callGetTakerAmount
và _callGetMakerAmount
chức năng. Các lệnh gọi này cung cấp cách tính toán một bên của hoán đổi dựa trên bên kia và chúng cho phép người dùng thực hiện một phần đơn đặt hàng.
Sản phẩm getTakerAmount
/getMakerAmount
các trường là các biến động và được đóng gói ở phía trước takerAmount
và makerAmount
giá trị trong _callGetTakerAmount
và _callGetMakerAmount
chức năng. Kẻ tạo mã độc có thể cung cấp nhiều dữ liệu hơn mong đợi trong getTakerAmount
vàgetMakerAmount
các trường để đẩy takerAmount
và makerAmount
byte đã qua nơi chúng được giả định khi được giải mã trong hàm tiếp theo. Điều này cho phép nhà sản xuất dịch chuyển số lượng bên nhận hoặc nhà sản xuất đã chuyển sang bên phải một byte đầy đủ và thậm chí thay thế chúng hoàn toàn nếu cung cấp thêm 32 byte dữ liệu.
Người dùng đã phải xem lại thủ công getTakerAmount
và getMakerAmount
các trường theo thứ tự, nhưng kỹ thuật này khá khó phát hiện. Cũng đáng lưu ý, cuộc tấn công này thậm chí còn áp dụng cho các cơ quan được tin cậy nội bộ. getMakerAmount
và getTakerAmount
chức năng. Đối với hầu hết các cuộc tấn công, việc cung cấp số tiền ngưỡng hợp lý sẽ ngăn chặn việc mất tiền.
Để ngăn chặn điều này, hãy cân nhắc việc mã hóa các đối số tĩnh trước các đối số động để tránh cung cấp cho các đối số động một phương thức kiểm soát các đối số tĩnh.
Cập nhật: Không cố định. Nhóm 1inch tuyên bố:
Chúng tôi sẽ cẩn thận hơn với việc xác thực getters. Chúng tôi sẽ cố gắng triển khai xác thực độ chính xác của getters trong sdk của mình để giúp lọc các đơn hàng có khả năng độc hại.
[M02] Lệnh ERC721 có thể được thao tác
Có thể trao đổi nhiều hơn chỉ ERC20 thông qua OrderMixin
bằng cách triển khai một hợp đồng có chung bộ chọn chức năng như IERC20 transferFrom
, và cung cấp hợp đồng đó với tư cách là makerAsset
hoặc là takerAsset
trong một đơn đặt hàng.
Các proxy ngoài phạm vi, cụ thể là, ERC721Proxy
, ERC721ProxySafe
và ERC1155Proxy
hợp đồng tuân theo mô hình này để cung cấp hỗ trợ cho ERC721
và ERC1155
mã thông báo. Vì các proxy phải được gọi có cùng mẫu với IERC20 transferFrom
cuộc gọi, chữ ký phải bắt đầu bằng address from
, address to
và uint256 amount
. Bất cứ điều gì khác mà proxy yêu cầu đều có thể được chuyển vào sau và được xác định theo thứ tự là makerAssetData
và takerAssetData
.
ERC1155 có thể chuyển nhiều mã thông báo id giống nhau cùng một lúc một cách tự nhiên, điều đó có nghĩa là ERC1155Proxy
hợp đồng sử dụng amount
cánh đồng. Mặt khác, ERC721
s không có cách sử dụng rõ ràng cho amount
cánh đồng. Vì chúng đại diện cho các mã thông báo không thể thay thế được nên một tokenId cụ thể sẽ chỉ tồn tại một mã thông báo, hiển thị amount
trường vô dụng. Bởi vì điều này, việc thực hiện cho cả hai ERC721Proxy
và ERC721ProxySafe
hợp đồng sử dụng yêu cầu amount
lĩnh vực như tokenId
thay thế.
Sự quá tải này của amount
tham số tạo ra khả năng lấp đầy một phần ERC721
đơn đặt hàng để mua mã thông báo được liệt kê riêng với giá chiết khấu. Ví dụ: có thể có trường hợp một người dùng có nhiều ERC721
của cùng một hợp đồng được phép chuyển nhượng bởi ERC721Proxy
hợp đồng và liệt kê chúng theo các lệnh giới hạn riêng biệt.
Nếu lệnh giới hạn cũng cung cấp getMakerAmount
và getTakerAmount
các trường này, bạn có thể điền một phần vào các trường này ERC721
đơn đặt hàng. Kể từ khi đơn đặt hàng amount
trường thực sự tương ứng với tokenId
, một người dùng độc hại có thể điền một phần vào ERC721
với tokenId cao hơn, dẫn đến makingAmount
/takingAmount
của một ERC721
có thể tương ứng với mức thấp hơn tokenId
. Kết quả là ERC721
với thấp hơn tokenId
sẽ được chuyển nhượng với giá (higher tokenId price) * (lower tokenId's id) / (higher tokenId's id)
.
Khai thác này có một số yêu cầu:
- nhiều
ERC721
s từ cùng một hợp đồng được phép trên một trong haiERC721
proxy bởi một chủ sở hữu duy nhất. - Mở lệnh cho một trong những
ERC721
s đó không phải là thấp nhấttokenId
trong số những cái được phép. - Cho phép điền một phần theo thứ tự.
Để loại bỏ hoàn toàn khả năng một phần ERC721
lấp đầy, hãy xem xét việc tách amount
và tokenId
tranh luận. Cho dù các đối số có được tách riêng hay không, hãy cân nhắc việc ghi lại điều này để cảnh báo người dùng về hành vi này và tránh mô hình này trong tương lai.
Cập nhật: Cố định yêu cầu kéo # 59.
[M03] Giả định thập phân không có giấy tờ
Sản phẩm LimitOrderProtocol
hợp đồng kế thừa ChainlinkCalculator
hợp đồng thông qua OrderMixin
hợp đồng. Hợp đồng này cung cấp hai chức năng cho phép sử dụng các oracle của Chainlink trong quá trình kiểm tra vị ngữ và tra cứu của số tiền của nhà sản xuất/số tiền người nhận.
Tuy nhiên, hợp đồng đưa ra các giả định không có giấy tờ về số lượng số thập phân mà các nhà tiên tri Chainlink phải báo cáo, cũng như số lượng số thập phân mà các tham số hàm phải chứa. Trong một số trường hợp nhất định, điều này có thể dẫn đến những hành vi không mong muốn, bao gồm việc định giá sai tài sản và mất tiền ngoài ý muốn.
Cụ thể hơn, trong suốt hợp đồng, giả định ngầm định là các nhà tiên tri Chainlink sẽ báo cáo với độ chính xác là 18 số thập phân. Tuy nhiên, không tất cả các oracle của Chainlink báo cáo với số thập phân này. Trên thực tế, nếu nhà tiên tri báo cáo một cặp mã thông báo tính theo đơn vị tiền tệ (chẳng hạn như USD), thì nó sẽ chỉ có độ chính xác là 8 số thập phân. Vì không có hạn chế về cái nào có thể sử dụng oracles, nhưng không nên đưa ra các giả định ngầm về số lượng số thập phân mà chúng sẽ báo cáo.
Liên quan, có một giả định ngầm rằng amount
tham số cho ChainlinkCalculator
các hàm sẽ sử dụng 18 số thập phân, cùng với tuyên bố rõ ràng gây hiểu lầm rằng singlePrice
chức năng Calculates price of token relative to ETH scaled by 1e18
. Trong thực tế, ngay cả với một lời tiên tri rằng làm báo cáo có 18 số thập phân, giá trị trả về của singlePrice
hàm sẽ được chia tỷ lệ theo số thập phân của amount
tham số, có thể không nhất thiết phải là 18 số thập phân.
Tương tự, doublePrice
hàm giả định rằng hai nhà tiên tri Chainlink sẽ báo cáo có cùng số thập phân, khiến kết quả của hàm sai lệch so với mong đợi.
Hãy xem xét ghi lại rõ ràng các giả định về số thập phân mà các tham số và giá trị trả về phải tuân theo. Hơn nữa, hãy xem xét việc giới hạn các phép tính phụ thuộc vào các lời tiên tri phá vỡ các giả định đó hoặc việc tính toán các phép tính liên quan có tính đến số thập phân thực tế.
Cập nhật: Cố định yêu cầu kéo # 75.
Mức độ nghiêm trọng thấp
[L01] Các hằng số không được khai báo rõ ràng
Có một số trường hợp giá trị bằng chữ được sử dụng với ý nghĩa không giải thích được trong cơ sở mã. Ví dụ:
- Trong tạp chí
OrderMixin
hợp đồng,_remaining
ánh xạ bị quá tải về mặt ngữ nghĩa (như được giải thích trong vấn đề Quá tải ngữ nghĩa của ánh xạ) để theo dõi số lượng tài sản còn lại cho đơn hàng đã được thực hiện một phần cũng như nếu một đơn đặt hàng đã được thực hiện đầy đủ. Đặc biệt,0
có nghĩa là không có lệnh thực hiện nào liên quan đến đơn hàng được thực hiện,1
có nghĩa là một đơn đặt hàng không thể được thực hiện nữa và bất cứ điều gì lớn hơn1
có nghĩa là số tiền còn lại liên quan đến đơn hàng có khả năng được thực hiện. - Trong tạp chí
ChainlinkCalculator
hợp đồng, giá trị thực tế1e18
được sử dụng trongsinglePrice
chức năng.
Để cải thiện khả năng đọc mã và tạo điều kiện thuận lợi cho việc tái cấu trúc, hãy cân nhắc việc xác định một hằng số cho mọi số ma thuật, đặt cho nó một cái tên rõ ràng và dễ hiểu. Đối với các giá trị phức tạp, hãy cân nhắc thêm nhận xét nội tuyến giải thích cách tính chúng hoặc lý do chúng được chọn.
Cập nhật: Cố định yêu cầu kéo # 75 và yêu cầu kéo # 76.
[L02] Các bên độc hại có thể ngăn cản việc thực hiện các lệnh được phép
Sản phẩm OrderMixin
hợp đồng cho phép người dùng nhà sản xuất gửi đơn đặt hàng cho phép vì vậy những giao dịch đó có thể được thực hiện trong một giao dịch, thay vì phải có một giao dịch riêng để được phê duyệt. Ngoài ra, người nhận đặt hàng có thể nộp giấy phép riêng của họ trong quá trình thực hiện đơn đặt hàng cho cùng một mục đích.
Tuy nhiên, vì giấy phép của nhà sản xuất được chứa đựng bên trong gọi món, cả giấy phép của người tạo và người nhận đều có thể truy cập được trong khi giao dịch điền đơn hàng nằm trong mempool. Điều này sẽ giúp bất kỳ người dùng độc hại nào cũng có thể lấy các giấy phép đó và thực thi chúng trên các hợp đồng tài sản tương ứng trong khi thực hiện giao dịch thực hiện trước. Bởi vì những giấy phép này có nonce
để ngăn chặn một cuộc tấn công chi tiêu gấp đôi, giao dịch thực hiện đơn đặt hàng sẽ không thành công do cố gắng sử dụng cùng một giấy phép vừa được sử dụng trong lần chạy trước.
Mặc dù không có rủi ro bảo mật và nhà sản xuất có thể tạo đơn hàng mới và phê duyệt trước giao dịch, cuộc tấn công này chắc chắn có thể ảnh hưởng đến khả năng sử dụng của các đơn hàng được phép. Thật vậy, kẻ tấn công có động cơ có thể chặn tất cả các mệnh lệnh cho phép với cuộc tấn công này. Xem xét việc xác nhận xem giấy phép đã được nộp hay chưa hoặc liệu mức trợ cấp có đủ hay không trong quá trình thực hiện đơn hàng. Đồng thời, hãy cân nhắc việc cho người dùng biết về cuộc tấn công có thể xảy ra này trong quá trình soạn đơn hàng.
Cập nhật: Không cố định. Nhóm 1inch tuyên bố:
Trước đây, chúng tôi đã kiểm tra phê duyệt nhưng đã quyết định đơn giản hóa quy trình cấp phép để hoàn nguyên các phê duyệt không thành công. Chúng tôi sẽ nghĩ cách thông báo cho nhà sản xuất về vấn đề này.
[L03] Mã trùng lặp
Có những trường hợp mã trùng lặp trong cơ sở mã. Mã trùng lặp có thể dẫn đến các vấn đề sau này trong vòng đời phát triển và khiến dự án dễ gặp lỗi hơn. Những lỗi như vậy có thể vô tình xuất hiện khi các thay đổi về chức năng không được sao chép trên tất cả các phiên bản mã giống hệt nhau. Ví dụ về mã trùng lặp bao gồm:
Thay vì sao chép mã, hãy cân nhắc việc chỉ có một hợp đồng hoặc thư viện chứa mã trùng lặp và sử dụng nó bất cứ khi nào cần có chức năng sao chép.
Cập nhật: Đã sửa một phần trong yêu cầu kéo # 60.
[L04] Bộ thử nghiệm sai sót hoặc gây nhầm lẫn
Có những trường hợp trong bộ thử nghiệm mà các thử nghiệm đi chệch khỏi hành vi mong đợi của chúng. Ví dụ:
- Sản phẩm
ChainlinkCalculator
hợp đồng được kế thừa bởiOrderMixin
hợp đồng. Tuy nhiên, trong quá trình thử nghiệm,AmountCalculator.arbitraryStaticCall
Hàm được sử dụng để gọiChainlinkCalculator
hợp đồng như một hợp đồng bên ngoài, độc lập. Mặc dù kết quả đúng như mong đợi, nhưng thử nghiệm sẽ phản ánh hành vi với thiết kế hiện tại của hệ thống và trường hợp sử dụng dự kiến bằng cách gọiChainlinkCalculator
hoạt động trực tiếp mà không cần sử dụng lệnh gọi tĩnh tùy ý. - Mặc dù các hợp đồng proxy nằm ngoài phạm vi, chúng tôi nhận thấy rằng khi thử nghiệm giao thức với nội dung ERC721,
ERC721Proxy
hợp đồng không được sử dụng để hoán đổi tài sản trong hợp đồng đó. bộ thử nghiệm.
Vì bản thân bộ kiểm thử nằm ngoài phạm vi kiểm tra này, vui lòng xem xét kỹ lưỡng bộ kiểm thử để đảm bảo tất cả các kiểm thử đều chạy thành công theo các thông số kỹ thuật của giao thức.
Cập nhật: Cố định yêu cầu kéo # 57, yêu cầu kéo # 59và yêu cầu kéo # 61.
[L05] Lỗi và thiếu sót trong các sự kiện
Trong suốt cơ sở mã, các sự kiện thường được phát ra khi các thay đổi nhạy cảm được thực hiện đối với hợp đồng. Tuy nhiên, nhiều sự kiện thiếu thông số được lập chỉ mục và/hoặc thiếu thông số quan trọng. Ví dụ:
Ngoài ra còn có những hành động nhạy cảm đang thiếu sự kiện như:
Hãy cân nhắc việc lập chỉ mục đầy đủ hơn cho các sự kiện hiện có và thêm thông số mới vào những nơi còn thiếu. Ngoài ra, hãy cân nhắc việc phát hành tất cả các sự kiện theo cách hoàn chỉnh để chúng có thể được sử dụng để xây dựng lại trạng thái hợp đồng bằng các dịch vụ ngoài chuỗi.
Cập nhật: Không cố định. Tuy nhiên, nhóm 1inch đã thêm một orderRemaining
tham số cho OrderCanceled
sự kiện trong yêu cầu kéo # 62.
Nhóm 1inch tuyên bố:
Chúng tôi nhận thấy rằng chỉ cần một tập hợp con dữ liệu hạn chế để đáp ứng nhu cầu về giao diện người dùng. Trong trường hợp phân tích sâu rộng, tất cả các trường được đề xuất đều có sẵn thông qua truy tìm. Vì
OrderRFQMixin
chúng tôi hy vọng các nhà tạo lập thị trường sẽ xây dựng cách thức phức tạp của riêng họ để theo dõi những đơn hàng nào đã bị hủy.
[L06] Thay đổi lưu trữ trong quá trình phát sự kiện
Trong tạp chí NonceManager
hợp đồng, khi NonceIncreased
sự kiện được phát ra, nonce của người gửi tin nhắn cũng tăng lên.
Việc thực thi đồng thời nhiều thao tác có thể khiến cơ sở mã khó lý giải hơn, dễ xảy ra lỗi hơn và có thể dẫn đến các thao tác bị bỏ qua hoặc hiểu sai.
Để cải thiện tính chủ ý tổng thể, khả năng đọc và độ rõ ràng của mã, hãy cân nhắc việc tăng giá trị nonce trước khi phát ra sự kiện.
Cập nhật: Cố định yêu cầu kéo # 63.
[L07] Các phương pháp giải mã không nhất quán có thể gây ra sự khác biệt về kết quả
Để hỗ trợ tất cả khả năng mở rộng và tính linh hoạt của nó, Giao thức lệnh giới hạn thường xuyên phải xử lý dữ liệu byte động và các giá trị trả về tùy ý từ các hợp đồng bên ngoài. Kết quả là, giao thức bao gồm một ArgumentsDecoder
thư viện để chuyển đổi các giá trị byte động thành các kiểu dữ liệu cơ bản hiệu quả hơn. Tuy nhiên, thư viện này không được sử dụng riêng và trong một số trường hợp abi.decode
được sử dụng thay thế. Ngoài ra, một số hợp đồng đang sử dụng abi coder v1
trong khi những người khác đang sử dụng abi coder v2
. Cái trước thực hiện tương tự như ArgumentsDecoder
thư viện, trong khi thư viện sau thực hiện kiểm tra bổ sung khi giải mã.
Việc sử dụng không nhất quán các phương pháp giải mã khác nhau này có thể dẫn đến sự khác biệt nhỏ giữa ý định và hành vi thực tế của cơ sở mã.
Ví dụ, các simulateCalls
chức năng chỉ sử dụng ArgumentsDecoder.decodeBool
chức năng. Nếu simulateCalls
được sử dụng để kiểm tra các lệnh gọi sẽ được thực hiện trong phần vị ngữ của một đơn hàng, khi đó kết quả của nó có thể khác với những gì thực sự xảy ra khi đánh giá các điều kiện vị ngữ, bởi vì các phương pháp giải mã khác nhau được sử dụng.
Vì vậy, ví dụ, nếu một vị từ tạo ra một ngoại tại staticcall
đến một số hàm trả về một uint256
giá trị lớn hơn một thay vì mong đợi bool
, thì lệnh gọi đó sẽ hoàn nguyên vì giá trị trả về là giải mã bằng abi coder v2
'S abi.decode
sẽ không chấp nhận các giá trị như bool
. Tuy nhiên, nếu cuộc gọi tương tự được thực hiện với simulateCalls
, sau đó nó sẽ chỉ được đánh dấu là true
, bởi vì decodeBool
coi mọi giá trị lớn hơn 0 là true
.
Để làm cho simulateCalls
phản ánh đầy đủ hành vi của các lệnh gọi vị ngữ thực tế, hãy xem xét sửa đổi nó để sử dụng abi.decode
.
Cập nhật: Cố định yêu cầu kéo # 82.
[L08] Thiếu xác thực đầu vào
Sản phẩm fillOrderToWithPermit
và fillOrderTo
chức năng của OrderMixin
hợp đồng cũng như fillOrderRFQToWithPermit
và fillOrderRFQTo
chức năng của OrderRFQMixin
hợp đồng, không xác nhận target
tham số địa chỉ.
Điều này khiến người dùng có thể vô tình chuyển địa chỉ số 0 và kết quả là khóa tài sản mà họ dự định nhận sau khi điền đơn đặt hàng.
Để đảm bảo rằng người dùng không vô tình khóa tiền của họ, hãy cân nhắc việc xác thực rằng target
địa chỉ không bằng địa chỉ 0 trong các hàm được trích dẫn.
Cập nhật: Cố định yêu cầu kéo # 78.
[L09] Phạm vi kiểm tra đơn vị thấp
Phạm vi kiểm tra đơn vị cho toàn bộ dự án là khoảng 75%, với một số hợp đồng có phạm vi bảo hiểm đặc biệt thấp.
Xem xét tầm quan trọng của các bài kiểm tra đơn vị để xác thực mã và ngăn chặn sự hồi quy khi tái cấu trúc và phát triển các tính năng mới, chúng tôi khuyến khích tăng đáng kể phạm vi kiểm tra đơn vị lên ít nhất 95% và bao gồm cả các trường hợp đặc biệt có thể bao gồm cả những tình huống khó xảy ra.
Cập nhật: Không cố định.
[L10] Tài liệu nội tuyến gây hiểu lầm hoặc không đầy đủ
Trong suốt cơ sở mã, một số trường hợp tài liệu nội tuyến gây hiểu lầm và/hoặc không đầy đủ đã được xác định và cần được khắc phục.
Sau đây là các trường hợp tài liệu nội tuyến gây hiểu lầm:
- Trong tạp chí
ChainlinkCalculator
hợp đồng,singlePrice
chức năng NatSpec@notice
tag nói rằng nóCalculates price of token relative to ETH scaled by 1e18
, nhưng trên thực tế, kết quả của nó là giá trị ofamount
mã thông báo được chia tỷ lệ theo1e18
, trong đó nhà tiên tri có thể không báo cáo về ETH (ví dụ: đối với một cặp không bao gồm ETH). - Trong tạp chí
OrderRFQMixin
hợp đồng,invalidatorForOrderRFQ
chức năng NatSpec@return
tag là sai lệch vì báo giá có thể chưa được điền cho bit vô hiệu hóa tương ứng đã được đặt. Đơn đặt hàng cũng có thể đã bị hủy. - Trên dòng 147, 165và 188 of
OrderMixin.sol
, NatSpec@param
các thẻ không đúng ngữ pháp. - Trực tuyến 20 of
ERC1155Proxy.sol
, Các@notice
thẻ nói rằng hàm băm được tính toán là kết quả của việc bămfunc_733NCGU
chức năng, nơi nó phải làfunc_301JL5R
chức năng thay thế.
Sau đây là các trường hợp tài liệu nội tuyến không đầy đủ:
- Các chức năng trong
AmountCalculator
hợp đồng không mô tả bất kỳ thông số nào. - Trong tạp chí
ChainlinkCalculator
hợp đồng,singlePrice
vàdoublePrice
chức năng không mô tả tất cả các tham số. - Trong tạp chí
ImmutableOwner
hợp đồng, biến công khai và công cụ sửa đổi không có NatSpec. - Trong tạp chí
InteractiveNotificationReceiver
hợp đồng,notifyFillOrder
hàm không mô tả bất kỳ tham số nào. - Trong tạp chí
LimitOrderProtocol
hợp đồng,DOMAIN_SEPARATOR
hàm không có NatSpec. - Sự kiện và ánh xạ trong
NonceManager
không có NatSpec. - Trong tạp chí
OrderRFQMixin
hợp đồng,cancelOrderRFQ*
các hàm không mô tả các giá trị trả về. - Trong tạp chí
OrderMixin
hợp đồng, một số chức năng thiếu NatSpec hoàn chỉnh. - Trực tuyến 168 of
OrderMixin.sol
và trực tuyến 71 ofOrderRFQMixin.sol
, nó thiếu@dev
tag. - Các chức năng trong
PredicateHelper
hợp đồng không mô tả tất cả các thông số.
Tài liệu nội tuyến rõ ràng là nền tảng để phác thảo ý định của mã. Sự không khớp giữa tài liệu nội tuyến và việc triển khai có thể dẫn đến những quan niệm sai lầm nghiêm trọng về cách hệ thống dự kiến sẽ hoạt động. Hãy cân nhắc sửa những lỗi này để tránh nhầm lẫn cho nhà phát triển, người dùng và người kiểm tra.
Cập nhật: Đã sửa một phần. Tài liệu gây hiểu lầm được đề cập trong yêu cầu kéo # 75 và yêu cầu kéo # 77.
Nhóm 1inch tuyên bố:
Chúng tôi đã sửa các tài liệu gây hiểu lầm. Việc hoàn thành các tài liệu sẽ được thực hiện sau.
[L11] Có thể đặt hàng DoS khi sử dụng hook
Sản phẩm OrderMixin
hợp đồng triển khai chức năng để thực hiện các lệnh hoán đổi chung ngoài chuỗi có thể có điều kiện cho sự thành công của chúng. Trong quá trình thực hiện đơn hàng, đơn hàng có thể kiểm tra các điều kiện “vị ngữ” được xác định trước trước khi tiếp tục thực hiện.
Tuy nhiên, vì các điều kiện vị ngữ này có thể nhắm mục tiêu logic của bất kỳ hợp đồng tùy ý nào, kẻ tạo ác ý có thể lừa người thực hiện tin rằng một lệnh hoạt động chính xác và nó hợp lệ khi kiểm tra nó ngoài chuỗi, nhưng sau đó lại thất bại khi cố gắng thực hiện cùng một lệnh trên chuỗi. Sự thay đổi trong hành vi vị ngữ này có thể được thực hiện bằng cách chạy trước một số trạng thái biến đổi mà vị từ phụ thuộc vào, bằng cách kiểm tra khí được gửi hoặc thậm chí địa chỉ nào có liên quan đến cuộc gọi hoặc bằng một số logic khác.
Hơn nữa, nếu nhà sản xuất xác định một tương tác trong quá trình trao đổi, Các interactionTarget
hợp đồng có thể tự hoàn nguyên hoặc thu hồi khoản trợ cấp để ngăn chặn việc thực hiện đơn hàng thành công, về cơ bản dẫn đến kết quả tương tự như các vị từ độc hại.
Mặc dù tài sản sẽ không gặp rủi ro, nhưng người dùng hoặc bot tìm được đơn hàng thuận lợi sẽ phải chịu gánh nặng lớn hơn khi cố gắng xác định các loại đơn đặt hàng spam mà bề ngoài có vẻ hợp pháp này. Trong trường hợp họ không xác định được các loại đơn đặt hàng này, họ sẽ phải chịu chi phí gas lãng phí. Để giảm số lượng đơn hàng spam, hãy cân nhắc việc hạn chế các mục tiêu có sẵn cho những hook này. Đồng thời, hãy cân nhắc cảnh báo người dùng về khả năng này trước khi họ cố gắng thực hiện đơn đặt hàng.
Cập nhật: Không cố định. Nhóm 1inch tuyên bố:
Chúng tôi xử lý vấn đề đó trong phần phụ trợ của mình và chúng tôi sẽ nghĩ về cách thông báo cho những người có khả năng thực hiện về vấn đề này.
[L12] Làm tròn có thể không thuận lợi cho taker
Trong tạp chí OrderMixin
và OrderRFQMixin
hợp đồng, khi một đơn hàng đang được thực hiện và người nhận chỉ cung cấp một makingAmount
or takingAmount
số tiền đó, giao thức sẽ cố gắng tính toán số tiền đối ứng của giao dịch hoán đổi.
Có hai vấn đề với những phép tính này, vấn đề đầu tiên là không có tài liệu hoặc logic nào giới hạn số thập phân mà tham số số lượng nên sử dụng, vấn đề mà chúng tôi đã giải quyết trong phần Giả định thập phân không có giấy tờ vấn đề.
Vấn đề thứ hai là trong quá trình tính toán này, giao thức sẽ có lợi cho nhà sản xuất. Vấn đề làm tròn có thể trở nên trầm trọng hơn khi các giả định thập phân ngầm bị phá vỡ, nhưng ngay cả khi mọi thứ đều nằm trong số hạng mong đợi, việc làm tròn sẽ xảy ra với số lượng nhỏ, lẻ.
Xem xét việc cho phép người thực hiện chỉ định số lượng tối thiểu makerAsset
tài sản mà họ sẵn sàng nhận cùng với số tiền tối đa takerAsset
tài sản mà họ sẵn sàng trao đổi, do đó việc chấp nhận bất kỳ cách làm tròn nào sẽ rõ ràng hơn.
Cập nhật: Không cố định. Nhóm 1inch tuyên bố:
Mức ngưỡng phải đủ để bảo vệ người nhận.
[L13] Xử lý thứ tự mâu thuẫn khi thiếu tham số
Trong tạp chí OrderMixin
hợp đồng, fillOrderTo
chức năng thực hiện các cuộc gọi nội bộ đến _callGetMakerAmount
và _callGetTakerAmount
hoạt động bất cứ khi nào cố gắng điền và makingAmount
hoặc là takingAmount
các tham số tương ứng bằng 0 hoặc nếu makingAmount
giá trị lớn hơn giá trị remainingMakerAmount
giá trị.
Sản phẩm _callGetMakerAmount
và _callGetTakerAmount
các cuộc gọi sẽ dẫn đến việc đảo ngược nếu đơn hàng không được tạo bằng getMakerAmount
or getTakerAmount
các tham số tương ứng và việc điền một phần đang được thực thi.
An bình luận nội tuyến bên cạnh _callGetMakerAmount
và một bình luận nội tuyến bên cạnh _callGetTakerAmount
tuyên bố rằng "chỉ cho phép điền toàn bộ" nếu đơn hàng không được tạo bằng getMakerAmount
or getTakerAmount
thông số.
Tuy nhiên, có những đường dẫn mã không áp dụng được điều này vì những đường dẫn đó không kiểm tra length
s của cả hai getMakerAmount
và getTakerAmount
thông số.
Cụ thể, khi một taker
chỉ định một takerAmount
giá trị cho một đơn hàng chỉ có một getMakerAmount
, trừ khi cuộc gọi đó đến getMakerAmount
trả về một số tiền lớn hơn remainingMakerAmount
, việc điền một phần có thể được thực thi trái ngược với tài liệu nội tuyến.
Điều này làm cho mục đích của những đường dẫn mã đó không rõ ràng. Nếu đây là hành vi dự kiến, hãy xem xét sửa đổi tài liệu nội tuyến để tài liệu rõ ràng hơn. Nếu đây là hành vi vô ý, hãy cân nhắc việc luôn kiểm tra độ dài của cả hai getMakerAmount
và getTakerAmount
tham số đồng thời để việc triển khai củng cố hành vi được mô tả bằng tài liệu nội tuyến.
Cập nhật: Cố định yêu cầu kéo # 79.
[L14] Sử dụng lệnh gọi Chainlink không còn được dùng nữa
Sản phẩm ChainlinkCalculator
hợp đồng được thiết kế để sử dụng để truy vấn các oracle của Chainlink. Nó làm như vậy thông qua việc thực hiện cuộc gọi đến latestTimestamp
và latestAnswer
phương pháp, cả hai đều không còn được dùng nữa. Trên thực tế, các phương thức này không còn xuất hiện trong API của trình tổng hợp Chainlink nữa kể từ phiên bản ba.
Để tránh những khả năng không tương thích trong tương lai với các nhà tiên tri Chainlink, hãy cân nhắc sử dụng latestRoundData
phương pháp thay thế.
Cập nhật: Cố định yêu cầu kéo # 67.
Ghi chú & Thông tin bổ sung
[N01] Không nhập giao diện
Sản phẩm AggregatorInterface
giao diện dường như là một tập hợp con mã được sao chép từ ChainLink
kho lưu trữ mã công khai của. Giao diện đầy đủ được bao gồm trong ChainLink
gói npm hợp đồng của.
Khi có thể, để giảm bớt khả năng xảy ra giao diện không khớp và các vấn đề phát sinh, thay vì xác định lại và/hoặc viết lại giao diện của dự án khác, hãy cân nhắc sử dụng giao diện được cài đặt qua gói npm chính thức của họ.
Cập nhật: Cố định yêu cầu kéo # 66.
[N02] Các phần phụ thuộc của dự án không được dùng nữa
Trong quá trình cài đặt sự phụ thuộc của dự án, NPM cảnh báo rằng một trong các gói được cài đặt, Highlight
, “sẽ không còn được hỗ trợ hoặc nhận các bản cập nhật bảo mật trong tương lai”.
Mặc dù gói này khó có thể gây ra rủi ro bảo mật nhưng hãy cân nhắc nâng cấp phần phụ thuộc sử dụng gói này lên phiên bản được bảo trì.
Cập nhật: Cố định yêu cầu kéo # 64.
[N03] Các cuộc gọi bên ngoài để xem các phương thức không phải là các cuộc gọi tĩnh
Trong hầu hết cơ sở mã, giao thức thực hiện các cuộc gọi bên ngoài một cách rõ ràng thông qua OpenZeppelin functionStaticCall
phương pháp để hạn chế khả năng thay đổi trạng thái khi chúng không được mong đợi hoặc không mong muốn. Tuy nhiên, trong ChainlinkCalculator
hợp đồng, mặc dù mục đích chỉ thực hiện các cuộc gọi bên ngoài tới view
các phương thức trên các oracle của Chainlink, các lệnh gọi bên ngoài trong singlePrice
và doublePrice
chức năng không được thực hiện thông qua rõ ràng staticcall
s.
Mặc dù chúng tôi không xác định được bất kỳ mối lo ngại bảo mật tức thời nào xuất phát từ vấn đề này, nhưng để giảm bề mặt tấn công, cải thiện tính nhất quán và làm rõ mục đích, hãy cân nhắc sử dụng staticcall
s, cho tất cả các cuộc gọi bên ngoài tới view
các chức năng trong ChainlinkCalculator
hợp đồng.
Cập nhật: Không cố định. Nhóm 1inch tuyên bố:
Chúng tôi cho rằng sự phức tạp về cú pháp sẽ vô hiệu hóa những cải tiến về tính nhất quán.
[N04] Không thất bại sớm với đơn hàng không hợp lệ
Trong tạp chí OrderMixin
hợp đồng, fillOrderTo
hàm xử lý điều kiện đặc biệt khi đơn hàng chưa được gửi trước đó (remainingMakerAmount == 0
), nhưng nó không xử lý rõ ràng điều kiện khi lệnh không còn hiệu lực (remainingMakerAmount == 1
).
Trong trường hợp thứ hai, chức năng này cuối cùng sẽ hoàn nguyên, nhưng chỉ sau khi đốt cháy một lượng khí không hề nhỏ. Để làm rõ mục đích, tăng khả năng đọc và giảm mức sử dụng gas, hãy xem xét xử lý rõ ràng tình huống thứ tự không hợp lệ ở đầu hàm.
Cập nhật: Cố định yêu cầu kéo # 68.
[N05] Hợp đồng trợ giúp không được đánh dấu là trừu tượng
Trong Solidity, từ khóa abstract
được sử dụng cho các hợp đồng không phải là hợp đồng chức năng hoặc không có mục đích sử dụng như vậy. Thay vì, abstract
các hợp đồng được kế thừa bởi các hợp đồng khác trong hệ thống để tạo ra các hợp đồng chức năng độc lập.
Xuyên suốt cơ sở mã, có những ví dụ về hợp đồng trợ giúp không được đánh dấu là trừu tượng, mặc dù thực tế là chúng không được thiết kế để tự triển khai. Ví dụ, AmountCalculator
, ChainlinkCalculator
, ImmutableOwner
, NonceManager
và PredicateHelper
tất cả các hợp đồng đều bao gồm một tập hợp các chức năng cơ bản được dự định sẽ được sử dụng bởi các hợp đồng kế thừa.
Hãy cân nhắc việc đánh dấu các hợp đồng trợ giúp là abstract
để biểu thị rõ ràng rằng chúng được thiết kế chỉ để bổ sung chức năng cho các hợp đồng kế thừa chúng.
Cập nhật: Không cố định. Nhóm 1inch tuyên bố:
Những người trợ giúp đó có thể được triển khai riêng biệt. Chúng được thừa kế chỉ để tiết kiệm xăng.
[N06] Thứ tự hàm không nhất quán
Trong suốt cơ sở mã, thứ tự hàm thường tuân theo thứ tự được đề xuất trong Hướng dẫn Phong cách Solidity, Đó là: constructor
, fallback
, external
, public
, internal
, private
.
Tuy nhiên, trong OrderMixin
hợp đồng, public
checkPredicate
hàm đi chệch khỏi hướng dẫn kiểu, chia đôi external
chức năng.
Để cải thiện mức độ dễ đọc tổng thể của dự án, hãy cân nhắc việc tiêu chuẩn hóa thứ tự hàm trong toàn bộ cơ sở mã, theo khuyến nghị của Hướng dẫn về Phong cách Solidity.
Cập nhật: Cố định yêu cầu kéo # 69.
[N07] Luồng điền đơn hàng không nhất quán
Sản phẩm OrderMixin
và RFQOrderMixin
cả hai hợp đồng đều xử lý việc thực hiện các đơn đặt hàng đã ký, nhưng luồng đơn hàng chung giữa hai hợp đồng không nhất quán.
OrderMixin
'S fillOrderTo
hàm tuân theo luồng chung này (mã giả):
if ((takingAmount == 0) == (makingAmount == 0))
else if (takingAmount == 0)
else (handle makingAmount == 0) THEN swapTokens
Trong khi đó, RFQOrderMixin
tương tự fillOrderRFQTo
hàm tuân theo luồng này (mã giả):
if (takingAmount == 0 && makingAmount == 0)
else if (takingAmount == 0)
else if (makingAmount == 0)
else revert THEN swapTokens
Không có thông tin chi tiết nào từ tài liệu về lý do tại sao điều kiện đầu tiên trong mỗi hàm trong số hai hàm này lại khác nhau hoặc tại sao takingAmount
và makingAmount
cả hai không thể bằng 0 trong hàm sau. Ngoài ra, trường hợp cả hai makingAmount
và takingAmount
được cung cấp dễ dàng hơn nhiều để lý luận trong fillOrderRFQTo
chức năng, vì nó được xử lý rõ ràng trong phần cuối cùng else
khối.
Để làm rõ mục đích và tăng khả năng đọc mã tổng thể, hãy xem xét tiêu chuẩn hóa quy trình đặt hàng chung giữa hai hợp đồng này hoặc ghi lại rõ ràng lý do tồn tại sự khác biệt.
Cập nhật: Không cố định. Nhóm 1inch tuyên bố:
Điều này là do chức năng định giá tùy chỉnh trong các đơn đặt hàng giới hạn. Từ
getMakerAmount
có khả năng có thể khác biệt đáng kể so vớigetTakerAmount
, chúng tôi nghĩ rằng tốt hơn hết là không nên tạo tùy chọn mặc định cho người nhận vì điều này có thể khiến họ nhầm lẫn trong trường hợp các phương thức nhận đó sẽ khác.
[N08] Thông báo lỗi có định dạng không nhất quán hoặc sai lệch
Trong suốt cơ sở mã, require
và revert
Thông báo lỗi nhằm thông báo cho người dùng về các điều kiện cụ thể khiến giao dịch không thành công, được phát hiện có định dạng không nhất quán.
Ví dụ: mỗi thông báo lỗi trên dòng 85 của OrderMixin.sol
, 16 của ERC721ProxySafe.sol
và 26 của Permitable.sol
sử dụng một phong cách khác.
Ngoài ra, một số thông báo lỗi có thể gây nhầm lẫn:
Thông báo lỗi nhằm mục đích thông báo cho người dùng về các điều kiện không thành công, vì vậy, chúng phải cung cấp đủ thông tin để có thể thực hiện các chỉnh sửa thích hợp nhằm tương tác với hệ thống. Thông báo lỗi không đầy đủ thông tin gây tổn hại lớn đến trải nghiệm chung của người dùng, do đó làm giảm chất lượng của hệ thống. Hơn nữa, các thông báo lỗi được định dạng không nhất quán có thể gây ra sự nhầm lẫn không cần thiết. Do đó, hãy cân nhắc việc xem lại toàn bộ cơ sở mã để đảm bảo mọi require
và revert
câu lệnh có thông báo lỗi được định dạng nhất quán, chính xác, nhiều thông tin và thân thiện với người dùng.
Cập nhật: Đã sửa một phần trong yêu cầu kéo # 81.
[N09] Việc sử dụng các biến trả về được đặt tên không nhất quán
Có sự sử dụng không nhất quán các biến trả về được đặt tên trong OrderMixin
hợp đồng. Một số chức năng trả về các biến được đặt tên, khác trả về giá trị rõ ràng, và những người khác khai báo một biến trả về được đặt tên nhưng ghi đè lên nó với một tuyên bố trở lại rõ ràng.
Hãy cân nhắc áp dụng một cách tiếp cận nhất quán để trả về các giá trị trong toàn bộ cơ sở mã bằng cách loại bỏ tất cả các biến trả về được đặt tên, khai báo rõ ràng chúng dưới dạng biến cục bộ và thêm các câu lệnh trả về cần thiết khi thích hợp. Điều này sẽ cải thiện cả tính rõ ràng và khả năng đọc của mã, đồng thời cũng có thể giúp giảm hiện tượng hồi quy trong quá trình tái cấu trúc mã trong tương lai.
Cập nhật: Cố định yêu cầu kéo # 73.
[N10] Tính toán băm của đơn hàng không được mở cho API
Sản phẩm external
chức năng remaining
, remainingRaw
và remainingsRaw
tất cả đều mong đợi một hàm băm đơn hàng để hoạt động thành công.
Tuy nhiên, chức năng trợ giúp _hash
, trả về hàm băm của một đơn hàng, có private
hiển thị. Điều này có nghĩa là người dùng sẽ phải đóng gói các phần của đơn hàng và chuỗi miền theo cách thủ công để có được hàm băm của đơn hàng.
Để tránh khả năng xảy ra sai sót khi tính toán hàm băm đơn hàng và cung cấp cho người dùng phương pháp tạo hàm băm tương ứng của đơn hàng, hãy xem xét mở rộng khả năng hiển thị của _hash
chức năng để public
và tái cấu trúc tên thành hash
để nhất quán với phần còn lại của mã.
Cập nhật: Cố định yêu cầu kéo # 74.
[N11] Quá tải ngữ nghĩa của ánh xạ
Sản phẩm _remaining
ánh xạ trong OrderMixin
hợp đồng bị quá tải về mặt ngữ nghĩa để theo dõi trạng thái của đơn đặt hàng và số lượng tài sản còn lại có sẵn cho các đơn hàng đó.
Ba trạng thái mà nó có thể đảm nhận là:
0
: Băm đơn hàng vẫn chưa được nhìn thấy.1
: Đơn hàng đã bị hủy hoặc đã được điền đầy đủ.- Bất kì
uint
to hơn1
: Phần còn lạimakerAmount
có sẵn để được điền vào đơn đặt hàng cộng với1
.
Quá tải ngữ nghĩa này yêu cầu gói và mở gói giá trị này trong quá trình lookup
, cancellation
, initialization
và storage
.
Quá tải ngữ nghĩa và logic cần thiết để kích hoạt nó có thể dễ bị lỗi và có thể làm cho cơ sở mã khó hiểu và khó giải thích hơn, nó cũng có thể mở ra cơ hội cho sự hồi quy trong các bản cập nhật mã trong tương lai.
Để cải thiện khả năng đọc mã, hãy cân nhắc việc theo dõi trạng thái hoàn thành của đơn hàng trong một ánh xạ riêng.
Cập nhật: Không cố định. Nhóm 1inch trích dẫn rằng việc sửa lỗi sẽ làm tăng chi phí gas cho fillOrder
chức năng.
[N12] Lệnh có giấy phép cho phép gọi tới hợp đồng tùy ý
Sản phẩm OrderMixin
hợp đồng kế thừa Permitable
hợp đồng cho phép thực hiện lệnh giao dịch đơn lẻ với các tài sản chấp nhận permit
kêu gọi sửa đổi phụ cấp.
Tuy nhiên, cuộc gọi đến Permitable
hợp đồng không xác thực xem mục tiêu có phải là tài sản được phép hay không, thậm chí nó có phải là tài sản hay không, điều này có thể cho phép người dùng độc hại chuyển địa chỉ của một hợp đồng tùy ý có thể thực hiện một lệnh gọi khác trước khi quá trình điền đơn hàng hoàn tất.
Mặc dù hợp đồng được được bảo vệ chống lại sự quay trở lại, việc giảm bề mặt tấn công và ngăn chặn việc gọi các hợp đồng bên ngoài trong quá trình thực thi luôn được khuyến khích. Xem xét việc hạn chế nội dung liên quan đến giấy phép đối với các nội dung liên quan đến đơn đặt hàng hoặc danh sách trắng nội dung cho giao thức.
Cập nhật: Không cố định. Nhóm 1inch tuyên bố:
OrderMixin
thực tế không có thông tin về token thực tế vìmakerAsset
vàtakerAsset
đôi khi là proxy hoặc các hợp đồng trung gian khác và thông tin về mã thông báo thực tế được lưu trữ trong một số byte tùy ý. Vì vậy không có cách nào khả thi để hạn chế tài sản nàopermit
được kêu gọi.
[N13] solhint
không bao giờ được kích hoạt lại
Xuyên suốt cơ sở mã, có một vài solhint-disable
các tuyên bố, đặc biệt là những tuyên bố trực tuyến 23 và trực tuyến 41 of RevertReasonParser.sol
, không kết thúc với solhint-enable
.
Ủng hộ sự rõ ràng và hạn chế nhất có thể khi vô hiệu hóa solhint
, cân nhắc sử dụng solhint-disable-line
or solhint-disable-next-line
thay vào đó, tương tự như dòng 16 của cùng một tập tin.
Cập nhật: Cố định yêu cầu kéo # 72.
[N14] Lỗi chính tả
Cơ sở mã chứa các lỗi chính tả sau:
Ngoài ra dự án của README
(nằm ngoài phạm vi kiểm tra này) có các lỗi chính tả sau:
Xem xét sửa những lỗi chính tả này để cải thiện khả năng đọc mã.
Cập nhật: Cố định yêu cầu kéo # 71 và yêu cầu kéo # 77.
[N15] Sử dụng uint
thay vì uint256
Để ủng hộ sự rõ ràng, tất cả các trường hợp của uint
nên được khai báo là uint256
. Đặc biệt, những người ở for
vòng lặp trên dòng 98 và 119 of OrderMixin.sol
và dòng 16 và 30 of PredicateHelper.sol
.
Cập nhật: Cố định yêu cầu kéo # 70.
Kết luận
3 vấn đề có mức độ nghiêm trọng cao đã được tìm thấy. Một số thay đổi đã được đề xuất để tuân theo các phương pháp hay nhất và giảm bề mặt tấn công tiềm ẩn.
- &
- 7
- Giới thiệu
- truy cập
- Theo
- Tài khoản
- ngang qua
- Hành động
- hành động
- thêm vào
- địa chỉ
- Lợi thế
- Tất cả
- Cho phép
- Đã
- Mặc dù
- số lượng
- phân tích
- api
- phương pháp tiếp cận
- đối số
- xung quanh
- tài sản
- Tài sản
- kiểm toán
- Back-end
- Bắt đầu
- được
- BEST
- thực hành tốt nhất
- Một chút
- chương trình
- xây dựng
- cuộc gọi
- mà
- trường hợp
- Nguyên nhân
- Chuỗi liên kết
- thay đổi
- kiểm tra
- Séc
- mã
- phức tạp
- điều kiện
- nhầm lẫn
- xây dựng
- chứa
- hợp đồng
- hợp đồng
- Sửa chữa
- Chi phí
- có thể
- Couple
- yaratıcı
- Tiền tệ
- Current
- dữ liệu
- nhiều
- Denial of Service
- triển khai
- Thiết kế
- phát triển
- Phát triển
- ĐÃ LÀM
- khác nhau
- khác nhau
- miền
- tăng gấp đôi
- năng động
- Đầu
- Cạnh
- khuyến khích
- đặc biệt
- ETH
- Sự kiện
- sự kiện
- tất cả mọi thứ
- ví dụ
- Sàn giao dịch
- dự kiến
- kinh nghiệm
- Khai thác
- Tính năng
- Lĩnh vực
- Cuối cùng
- Tên
- Sửa chữa
- Linh hoạt
- dòng chảy
- theo
- tìm thấy
- Full
- chức năng
- quỹ
- tương lai
- trò chơi
- GAS
- Tổng Quát
- Cho
- tuyệt vời
- hướng dẫn
- Xử lý
- băm
- băm
- có
- giúp đỡ
- Cao
- cao
- Độ đáng tin của
- HTTPS
- Hỗn hợp
- xác định
- Va chạm
- thực hiện
- quan trọng
- nhập khẩu
- bao gồm
- Bao gồm
- Tăng lên
- tăng
- Thông tin
- thông tin
- Cơ sở hạ tầng
- những hiểu biết
- ý định
- quan tâm
- Giao thức
- tham gia
- các vấn đề
- IT
- lớn
- lớn hơn
- dẫn
- hàng đầu
- Thư viện
- Hạn chế
- Dòng
- Thanh khoản
- Liệt kê
- Chức năng
- địa phương
- nhìn
- tra cứu
- chính
- nhà sản xuất
- Làm
- thị trường
- Hồi ức
- gương
- kiểu mẫu
- hầu hết
- Phổ biến nhất
- cụ thể là
- Các tính năng mới
- không nấm
- mã
- chính thức
- mở
- Hoạt động
- Tùy chọn
- oracle
- gọi món
- đơn đặt hàng
- Nền tảng khác
- chủ sở hữu
- Họa tiết
- Phổ biến
- trình bày
- ngăn chặn
- giá
- giá
- riêng
- quá trình
- dự án
- dự án
- bảo vệ
- giao thức
- cho
- cung cấp
- Proxy
- công khai
- xuất bản
- mua
- chất lượng
- nâng cao
- Thực tế
- giảm
- sự phụ thuộc
- báo cáo
- Báo cáo
- kho
- Yêu cầu
- REST của
- Kết quả
- Trả về
- xem xét
- Nguy cơ
- vòng
- chạy
- sdk
- an ninh
- DỊCH VỤ
- định
- chia sẻ
- cổ phiếu
- thay đổi
- tương tự
- Đơn giản
- nhỏ
- thông minh
- Hợp đồng thông minh
- So
- sự vững chắc
- thư rác
- đặc biệt
- Chi
- Spot
- Bắt đầu
- Tiểu bang
- Tuyên bố
- Bang
- Trạng thái
- là gắn
- phong cách
- trình
- thành công
- thành công
- Thành công
- hỗ trợ
- Hỗ trợ
- Bề mặt
- Công tắc điện
- hệ thống
- Mục tiêu
- thử nghiệm
- Kiểm tra
- kiểm tra
- Thông qua
- khắp
- thời gian
- bên nhau
- mã thông báo
- Tokens
- theo dõi
- Theo dõi
- giao dịch
- NIỀM TIN
- độc đáo
- Cập nhật
- us
- khả năng sử dụng
- Đô la Mỹ
- USDT
- Người sử dụng
- tiện ích
- giá trị
- Xem
- khả năng hiển thị
- chờ đợi
- Điều gì
- danh sách trắng
- ở trong
- không có
- Công việc
- giá trị
- không