Dicembre 16, 2021
Introduzione
I 1inch il team ci ha chiesto di rivedere e verificare i loro Protocollo d'ordine limite Contratti intelligenti v2. Abbiamo esaminato il codice e ora pubblichiamo i nostri risultati.
Obbiettivo
Abbiamo verificato il commit 4d94eea25e4dac6271bfd703096a5c4a4d899b4a
della 1inch/limit-order-protocol
deposito. Nel campo di applicazione rientravano i seguenti contratti:
- 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
Anche tutti gli altri file e directory di progetto (compresi i test), insieme a dipendenze e progetti esterni, teoria dei giochi e progettazione di incentivi, sono stati esclusi dall'ambito di questo audit. Si presupponeva che il codice esterno e le dipendenze del contratto funzionassero come documentato e si presumeva che i servizi back-end forniti da 1inch agissero nel migliore interesse del protocollo.
Salute generale
In generale, abbiamo trovato la base di codice del progetto leggibile e ben organizzata, anche se potrebbe trarre vantaggio da una documentazione più ampia, in particolare sui blocchi di codice assembly, casi limite del protocollo, risorse/predicati/risorse esterne che verranno utilizzate, responsabilità/limitazioni del servizio back-end fornito e interazioni tra gli attori. Il progetto fa di tutto per rendere le azioni efficienti dal punto di vista del gas, a volte anche con il rischio di rendere il codice più difficile da ragionare; solleviamo questioni relative a quella di seguito. Durante l'audit, il team di 1 pollice si è dimostrato altamente disponibile, reattivo e con cui è stato molto facile lavorare.
panoramica del sistema
Il protocollo dell'ordine limitato consente l'ordine makers
per firmare ordini fuori catena per gli scambi di token. Il protocollo facilita poi l'evasione degli ordini precedentemente firmati per ordine takers
. Gli ordini sono altamente estensibili e possono chiamare in modo statico contratti esterni in diversi punti del processo di compilazione dell'ordine. Questa estensibilità conferisce utilità al protocollo, ma aggiunge complessità e una maggiore superficie di attacco per gli ordini stessi.
È importante notare che non esiste alcuna memorizzazione on-chain dei dettagli dell'ordine. Lo stato di riempimento o di annullamento degli ordini viene monitorato solo tramite gli hash degli ordini. Ciò richiede che gli ordini siano condivisi peer-to-peer o tramite un soggetto centralizzato. In questo caso, il team da 1 pollice intende agire come parte centralizzata, aggregando gli ordini firmati e utilizzando tali ordini come fonte di liquidità per gli altri protocolli. Gli ordini verranno pubblicati tramite la propria API in modo che gli utenti possano interagire con essi.
Questa centralizzazione offre al team da 1 pollice un controllo estremo su quali ordini vengono pubblicati e infine eseguiti. Ciò dà loro anche la possibilità di censurare gli ordini, il che potrebbe essere utile in caso di ordini dannosi o ingannevoli, ma potrebbe anche essere oggetto di abusi e consentire loro di prevalere su qualsiasi altro utente in caso di ordine favorevole non mostrandolo tramite l'API.
Ruoli privilegiati
Sebbene i contratti in cui viene utilizzato il ruolo non rientrassero nell'ambito, è stato identificato un ruolo privilegiato. UN immutableOwner
è impostato sul creatore di un contratto di procura al momento della creazione e viene utilizzato per limitare l'accesso ai delegati external
funzioni.
Dipendenze esterne e ipotesi di fiducia
La progettazione di questo protocollo richiede componenti off-chain e on-chain e questo modello ibrido può essere utilizzato per mitigare alcuni vettori di attacco che identifichiamo nel nostro rapporto, ma il costo di tale capacità è una maggiore dipendenza dal team e dall'infrastruttura da 1 pollice.
Inoltre, il Limit Order Protocol fornisce funzioni destinate a recuperare i prezzi dagli oracoli di Chainlink. Abbiamo presupposto che quegli oracoli fossero onesti, accessibili e correttamente funzionanti.
Inoltre, a causa della flessibilità di un ordine, ci sono diversi punti di contatto con contratti esterni che non vengono convalidati. Ciò significa che un utente malintenzionato potrebbe abusare di tali chiamate e impersonare predicati, risorse o oracoli con contratti dannosi per eseguire azioni durante l'evasione degli ordini. Sebbene il progetto sia protetto in alcune aree contro il rientro, tali vettori potrebbero causare attacchi di negazione del servizio o ordini di spam non rilevati. Il team di 1 pollice è consapevole che potrebbero verificarsi alcuni problemi quando si utilizzano contratti non familiari per il protocollo e ha indicato la propria intenzione che solo le principali risorse "blue chip" saranno pienamente supportate dal progetto. Tuttavia, va notato che anche con gli asset più popolari ci sono comportamenti intrinseci di ciascun asset che possono causare problemi sui protocolli che non li affrontano correttamente, come avere una commissione durante i trasferimenti con USDT o restituire un codice di errore invece di un booleano di successo con cTokens.
Giudizio
Qui presentiamo i nostri risultati.
Gravità critica
Nessuno.
Elevata gravità
[H01] Dati incoerenti trasmessi _makeCall
Nel OrderMixin
contratto, il _makeCall
La funzione viene utilizzata per trasferire beni da chi prende a chi crea e poi dal creatore all'acquirente. In quest'ultimo trasferimento, il _makeCall
la funzione viene passata erroneamente all'ordine makerAsset
come ultimo parametro, quando dovrebbe essere quello dell'ordine makerAssetData
.
Di conseguenza, qualsiasi funzionalità proxy che si basa su makerAssetData
la discussione si romperà.
Per essere coerenti con la precedente chiamata a _makeCall
e per supportare completamente la funzionalità proxy, valuta la possibilità di aggiornare il file order.makerAsset
parametro order.makerAssetData
.
Aggiornare: Risolto in richiesta pull # 57.
[H02] Gli ordini privati parzialmente eseguiti possono essere eseguiti da chiunque
Il protocollo consente la creazione di ordini privati e pubblici. Su ordini privati, solo il allowedSender
l'indirizzo, specificato dal produttore durante la creazione dell'ordine, è in grado di evadere l'ordine.
Tuttavia, nel OrderMixin
contratto, convalida per il allowedSender
indirizzo ha un ambito errato, il che significa che viene valutato solo all'interno della logica che gestisce il primo riempimento di un ordine. Se un ordine privato è parzialmente eseguito, l'assegno per il allowedSender
l'indirizzo non è più raggiungibile e l'ordine diventa compilabile da chiunque.
Per chiarire l'intento riguardo se un utente debba essere in grado di evadere ordini privati parzialmente compilati o meno, prendere in considerazione la possibilità di documentare il motivo del comportamento attuale o di convalidare il allowedSender
indirizzo esterno all'ambito del primo riempimento per garantire che venga convalidato ogni volta che viene tentato un riempimento.
Aggiornare: Risolto in richiesta pull # 58.
[H03] Il produttore malintenzionato potrebbe trarre vantaggio dai riempimenti parziali per rubare le risorse dell'acquirente
Ordini da OrderMixin
il contratto può essere parzialmente riempito. Per supportare riempimenti parziali, il protocollo richiede un modo per calcolare entrambi i lati degli scambi. Entrambi getMakerAmount
ed getTakerAmount
i campi sono definiti dall'autore dell'ordine proprio per questo scopo.
Quando compilano un ordine, gli acquirenti devono fornire il file makingAmount
oppure takingAmount
valori così come a thresholdAmount
valore. È possibile adottare due diversi percorsi di codice, a seconda se il file makingAmount
oppure takingAmount
era fornito.
Il primo è quando il makingAmount
il parametro è definito. Potrebbe troncare , il makingAmount
valore e anche calcolare il takingAmount
valore per esso. In questa situazione, il thresholdAmount
assicura che il takingAmount
il valore preso è non inaspettatamente grande.
Il secondo è quando il takingAmount
il parametro è definito. In tal caso, lo farà calcolare il makingAmount
valore, con possibilità di troncandolo ed ricalcolando il takingAmount
valore se ciò accade. In questa situazione, il thresholdAmount
valore garantisce che il makingAmount
il valore restituito è non inaspettatamente piccolo.
Esistono due metodi di sfruttamento, ciascuno unico per uno dei percorsi di codice menzionati in precedenza. Questi metodi di sfruttamento richiedono malware getMakerAmount
ed getTakerAmount
funzioni. Una semplice implementazione di queste funzioni avrebbe un comportamento identico a AmountCalculator
'S getMakerAmount
ed getTakerAmount
funzioni, ma con un interruttore codificato che li costringerà a restituire un valore controllato dall'aggressore quando necessario.
Il primo modello di exploit, meno grave, coinvolge il primo percorso di codice in cui si trova il file makingAmount
il valore è specificato in un ordine di riempimento. Un produttore malintenzionato attenderebbe un ordine di riempimento che specifichi makingAmount
per presentarsi nel mempool per poterlo eseguire in anteprima. Prosciugherebbero tutto il valore tranne 1 dal lato del produttore e quindi forzerebbero _callGetTakerAmount
per restituire l'importo specificato nell'utente thresholdAmount
valore (o la loro indennità se è inferiore). Quando la transazione dell'utente viene finalmente completata, verrà scambiato l'intero importo thresholdAmount
vale la pena di takerAsset
per una singola unità di makerAsset
. Questo exploit è limitato dall'importo fornito dal thresholdAmount
valore o l'importo del takerAsset
l'utente ha consentito il LimitOrderProtocol
contrarre.
Il secondo modello di exploit, più grave, coinvolge il secondo percorso di codice in cui il file takingAmount
il valore è specificato. Allo stesso modo, il produttore malintenzionato attenderebbe un ordine di riempimento che specificasse a takingAmount
valore da visualizzare nel mempool. Avrebbero anticipato la transazione e forzato il makingAmount
valore restituito da _callGetMakerAmount
funzione essere superiore sia a remainingMakerAmount
e la thresholdAmount
. Avrebbero anche impostato il takingAmount
valore restituito da _callGetTakerAmount
essere l'importo di takerAsset
bene consentito sul LimitOrderProtocol
da parte dell'acquirente. Quando la transazione dell'acquirente andrà a buon fine, lo farà troncare il makingAmount
valore e poi ricalcolare il takingAmount
valore. Tuttavia non è garantito che questo ricalcolo sia inferiore e in questo caso prosciugherà l'acquirente di tutto takerAsset
che hanno consentito nel contratto. In questo percorso di codice, il thresholdAmount
valore è assicurando che il makingAmount
non è troppo basso, quindi prendendo tutti i prenditori takerAsset
la risorsa è deselezionata. I fondi persi sono limitati dall'importo del takerAsset
risorsa consentita dall'utente sul file LimitOrderProtocol
contrarre.
Questi exploit non sono possibili senza ordini parziali e, più specificamente, ordini parziali con dannosi getMakerAmount
ed getTakerAmount
implementazioni.
La questione principale del thresholdAmount
il controllo del valore è che copre solo un lato dello swap, ma l'altro lato può essere manipolato tramite frontrunning. Non ci sono garanzie che il valore originariamente proposto dall'acquirente rimanga invariato. Valuta la possibilità di rimuoverlo makingAmount
troncamento da entrambi i percorsi del codice e ripristino se l'ordine non può supportare un riempimento grande quanto richiesto. In questo modo, il thresholdAmount
può essere utilizzato per limitare sufficientemente l'altro lato dello scambio ed evitare comportamenti imprevisti, anche in ordini dannosi.
Aggiornare: Risolto in richiesta pull # 83.
Gravità media
[M01] Argomenti statici passati dopo gli argomenti dinamici
Nel OrderMixin
contratto, il getTakerAmount
ed getMakerAmount
i campi byte vengono utilizzati come argomenti per il file _callGetTakerAmount
ed _callGetMakerAmount
funzioni. Queste chiamate forniscono un modo per calcolare un lato dello swap in base all'altro e consentono agli utenti di eseguire parzialmente gli ordini.
I getTakerAmount
/getMakerAmount
i campi sono variabili dinamiche e sono compressi davanti al file takerAmount
ed makerAmount
valori in _callGetTakerAmount
ed _callGetMakerAmount
funzioni. È possibile che un produttore malintenzionato fornisca più dati del previsto nel file getTakerAmount
edgetMakerAmount
campi per spingere il takerAmount
ed makerAmount
byte passati dove si presuppone che siano quando vengono decodificati nella funzione successiva. Ciò consente al produttore di spostare l'importo passato nell'acquirente o nel produttore di un byte intero a destra e persino di sostituirli completamente se vengono forniti 32 byte di dati aggiuntivi.
Gli utenti devono già rivedere manualmente il file getTakerAmount
ed getMakerAmount
campi nell'ordine, ma questa tecnica è piuttosto difficile da individuare. Vale anche la pena notare che questo attacco si applica anche ai soggetti fidati internamente getMakerAmount
ed getTakerAmount
funzioni. Per la maggior parte degli attacchi, fornire una soglia ragionevole previene la perdita di fondi.
Per evitare ciò, valuta la possibilità di codificare gli argomenti statici prima degli argomenti dinamici per evitare di fornire agli argomenti dinamici un metodo per controllare gli argomenti statici.
Aggiornare: Non riparato. Il team di 1 pollice ha dichiarato:
Presteremo particolare attenzione alla convalida dei getter. Cercheremo di implementare la convalida dell'integrità dei getter nel nostro SDK che aiuterà a filtrare ordini potenzialmente dannosi.
[M02] Gli ordini ERC721 possono essere manipolati
È possibile scambiare più di semplici ERC20 tramite il file OrderMixin
implementando un contratto che condivide lo stesso selettore di funzioni di IERC20 transferFrom
, e fornendo tale contratto come makerAsset
oppure takerAsset
in un ordine.
I proxy fuori ambito, vale a dire, ERC721Proxy
, ERC721ProxySafe
e ERC1155Proxy
i contratti seguono questo modello per fornire supporto ERC721
ed ERC1155
gettoni. Poiché i proxy devono essere chiamati con lo stesso schema di un IERC20 transferFrom
chiamata, la firma deve iniziare con address from
, address to
ed uint256 amount
. Qualsiasi altra cosa richiesta dai proxy può essere passata successivamente ed è definita nell'ordine come makerAssetData
ed takerAssetData
.
Gli ERC1155 possono naturalmente trasferire più token ID contemporaneamente, il che significa che il file ERC1155Proxy
contratto si avvale del amount
campo. D'altra parte, ERC721
s non hanno un uso ovvio per il file amount
campo. Poiché rappresentano token non fungibili, un tokenId specifico ne avrà solo uno esistente, rendendo il file amount
campo inutile. Per questo motivo, l'implementazione per entrambi ERC721Proxy
ed ERC721ProxySafe
i contratti utilizzano il richiesto amount
campo come il tokenId
anziché.
Questo sovraccarico del amount
Il parametro crea la possibilità di riempimento parziale ERC721
ordini per acquistare gettoni elencati separatamente a prezzi scontati. Ad esempio, potrebbe verificarsi il caso in cui un singolo utente ne abbia più ERC721
s del medesimo contratto ammessi alla cessione da parte del ERC721Proxy
contratto e li elenca in ordini limite separati.
Se gli ordini limite forniscono anche il getMakerAmount
ed getTakerAmount
campi, sarà possibile riempirli parzialmente ERC721
ordini. Dall'ordine amount
il campo corrisponde effettivamente a tokenId
, un utente malintenzionato può inserire un riempimento parziale nel file ERC721
con il tokenId più alto, risultando in a makingAmount
/takingAmount
di ERC721
che potrebbe corrispondere ad un valore inferiore tokenId
. Il risultato è il ERC721
con l'inferiore tokenId
verrebbe trasferito al prezzo di (higher tokenId price) * (lower tokenId's id) / (higher tokenId's id)
.
Questo exploit ha alcuni requisiti:
- multiplo
ERC721
s dallo stesso contratto da consentire su entrambiERC721
delega da parte di un unico titolare. - Ordine aperto per uno dei
ERC721
Non è il più bassotokenId
di quelli ammessi. - Esecuzioni parziali consentite sull'ordine.
Per eliminare completamente la possibilità di parziale ERC721
riempie, considera la possibilità di separare il file amount
ed tokenId
argomenti. Indipendentemente dal fatto che gli argomenti siano separati o meno, valuta anche la possibilità di documentarlo per avvisare gli utenti di questo comportamento ed evitare questo schema in futuro.
Aggiornare: Risolto in richiesta pull # 59.
[M03] Presupposti decimali non documentati
I LimitOrderProtocol
il contratto eredita il ChainlinkCalculator
contratto attraverso il OrderMixin
contrarre. Questo contratto espone due funzioni per consentire l'utilizzo degli oracoli Chainlink durante il controllo dei predicati e la ricerca di importo del produttore/importo dell'acquirente.
Tuttavia, il contratto fa ipotesi non documentate sul numero di decimali che gli oracoli di Chainlink dovrebbero riportare, nonché sul numero di decimali che dovrebbero contenere i parametri della funzione. In alcuni scenari, ciò potrebbe portare a comportamenti imprevisti, tra cui la valutazione errata dei prezzi degli asset e la perdita involontaria di fondi.
Più specificamente, in tutto il contratto il presupposto implicito è che gli oracoli di Chainlink riporteranno con 18 decimali di precisione. Tuttavia no tutti gli oracoli di Chainlink riportare con questo numero di decimali. Infatti, se l'oracolo riporta una coppia di token espressa in termini di valuta (ad esempio USD), avrà solo 8 decimali di precisione. Poiché non ci sono restrizioni su quale possono essere utilizzati gli oracoli, non si dovrebbero fare ipotesi implicite sul numero di decimali con cui riporteranno.
In relazione a ciò, esiste un presupposto implicito che il amount
parametro per il ChainlinkCalculator
le funzioni utilizzeranno 18 decimali, insieme alla dichiarazione esplicita fuorviante che il singlePrice
function Calculates price of token relative to ETH scaled by 1e18
. In realtà anche con un oracolo tale effettua report con 18 decimali, il valore restituito del singlePrice
la funzione verrebbe ridimensionata in base al numero di decimali di amount
parametro, che potrebbe non essere necessariamente 18 decimali.
Allo stesso modo, il doublePrice
la funzione presuppone che due oracoli Chainlink riportino con lo stesso numero di decimali, facendo sì che il risultato della funzione si discosti dalle aspettative.
Prendi in considerazione la possibilità di documentare in modo esplicito le ipotesi relative al numero di decimali in termini di cui dovrebbero essere parametri e valori restituiti. Inoltre, valuta la possibilità di limitare i calcoli che dipendono da oracoli che infrangono tali presupposti o di fare in modo che i calcoli pertinenti tengano conto del numero effettivo di decimali.
Aggiornare: Risolto in richiesta pull # 75.
Bassa gravità
[L01] Costanti non dichiarate esplicitamente
Ci sono alcune occorrenze di valori letterali utilizzati con significato inspiegabile nel codebase. Per esempio:
- Nel
OrderMixin
contratto, il_remaining
la mappatura è semanticamente sovraccarica (come spiegato nel numero Sovraccarico semantico della mappatura) per tenere traccia dell'importo del bene rimanente per un ordine parzialmente eseguito così come se un ordine è stato completamente eseguito. Nello specifico,0
significa che non è stata effettuata alcuna evasione associata a un ordine,1
significa che un ordine non può più essere eseguito e qualsiasi cosa più grande di1
significa che c'è un importo residuo associato all'ordine che può potenzialmente essere eseguito. - Nel
ChainlinkCalculator
contratto, il valore letterale1e18
è usato nelsinglePrice
funzione.
Per migliorare la leggibilità del codice e facilitare il refactoring, valuta la possibilità di definire una costante per ogni numero magico, assegnandogli un nome chiaro e autoesplicativo. Per valori complessi, valuta la possibilità di aggiungere un commento in linea che spieghi come sono stati calcolati o perché sono stati scelti.
Aggiornare: Risolto in richiesta pull # 75 ed richiesta pull # 76.
[L02] I malintenzionati potrebbero impedire l'esecuzione degli ordini consentiti
I OrderMixin
il contratto consente agli utenti del produttore di inviare ordini consentiti quindi questi possono essere eseguiti in un'unica transazione, anziché dover avere una transazione separata per le approvazioni. Inoltre, gli acquirenti degli ordini possono farlo presentare la propria autorizzazione durante la compilazione dell'ordine per la stessa finalità.
Tuttavia, poiché il permesso del produttore è contenuto all'interno del file minimo, sia i permessi del produttore che quelli dell'acquirente sarebbero accessibili mentre la transazione di compilazione dell'ordine è nel mempool. Ciò consentirebbe a qualsiasi utente malintenzionato di prendere tali permessi ed eseguirli sui rispettivi contratti di asset mentre si esegue la transazione di riempimento. Poiché questi permessi hanno un nonce
per evitare un attacco di doppia spesa, la transazione di evasione dell'ordine fallirebbe a causa del tentativo di utilizzare lo stesso permesso appena utilizzato durante il frontrun.
Sebbene non vi sia alcun rischio per la sicurezza e il produttore possa creare un nuovo ordine e pre-approvare la transazione, questo attacco potrebbe sicuramente avere un impatto sull’utilizzabilità degli ordini consentiti. Infatti, un attaccante motivato potrebbe bloccare contro tutti i ordini consentiti con questo attacco. Valuta la possibilità di convalidare se il permesso è già stato presentato o se l'indennità è sufficiente durante l'esecuzione dell'ordine. Considera anche la possibilità di informare gli utenti di questo possibile attacco durante la composizione dell'ordine.
Aggiornare: Non riparato. Il team da 1 pollice afferma:
Avevamo già effettuato controlli di approvazione, ma abbiamo deciso di semplificare il flusso di autorizzazioni per tornare semplicemente alle approvazioni non riuscite. Penseremo alle modalità per avvisare i produttori del problema.
[L03] Codice duplicato
Sono presenti istanze di codice duplicato all'interno della codebase. La duplicazione del codice può portare a problemi più avanti nel ciclo di vita dello sviluppo e lascia il progetto più incline all'introduzione di errori. Tali errori possono essere introdotti inavvertitamente quando le modifiche alle funzionalità non vengono replicate in tutte le istanze di codice che dovrebbero essere identiche. Esempi di codice duplicato includono:
Invece di duplicare il codice, valuta la possibilità di avere un solo contratto o libreria contenente il codice duplicato e di utilizzarlo ogni volta che è richiesta la funzionalità duplicata.
Aggiornare: Parzialmente fissato in richiesta pull # 60.
[L04] Suite di test errata o fuorviante
Ci sono casi nella suite di test in cui i test si discostano dal comportamento previsto. Ad esempio:
- I
ChainlinkCalculator
il contratto viene ereditato dalOrderMixin
contrarre. Tuttavia, durante le prove ilAmountCalculator.arbitraryStaticCall
la funzione viene utilizzata per chiamare il fileChainlinkCalculator
contratto come un contratto esterno e indipendente. Anche se il risultato è quello previsto, il test dovrebbe riflettere il comportamento con la progettazione attuale del sistema e il caso d'uso previsto chiamandoChainlinkCalculator
funziona direttamente senza utilizzare la chiamata statica arbitraria. - Sebbene i contratti proxy non rientrassero nell'ambito, abbiamo notato che durante il test del protocollo con risorse ERC721, il file
ERC721Proxy
il contratto non viene utilizzato per scambiare le attività in esso contenute suite di prova.
Poiché la suite di test stessa non rientra nell'ambito di questo controllo, ti invitiamo a rivedere attentamente la suite di test per assicurarti che tutti i test vengano eseguiti con successo secondo le specifiche del protocollo.
Aggiornare: Risolto in richiesta pull # 57, richiesta pull # 59e richiesta pull # 61.
[L05] Errori e omissioni negli eventi
In tutta la base di codice, gli eventi vengono generalmente emessi quando vengono apportate modifiche sensibili ai contratti. Tuttavia, molti eventi non dispongono di parametri indicizzati e/o mancano parametri importanti. Per esempio:
Ci sono anche azioni sensibili a cui mancano eventi, come ad esempio:
Considera l'idea di indicizzare in modo più completo gli eventi esistenti e di aggiungere nuovi parametri dove mancano. Inoltre, valuta la possibilità di emettere tutti gli eventi in modo così completo da poter essere utilizzati per ricostruire lo stato del contratto da parte dei servizi off-chain.
Aggiornare: Non riparato. Tuttavia, il team da 1 pollice ha aggiunto un file orderRemaining
parametro per il OrderCanceled
evento in richiesta pull # 62.
Il team da 1 pollice afferma:
Abbiamo scoperto che è necessario solo un sottoinsieme limitato di dati per soddisfare le esigenze del frontend. In caso di analisi approfondita tutti i campi suggeriti sono disponibili tramite tracciamento. Per
OrderRFQMixin
ci aspettiamo che i market maker costruiscano il proprio modo sofisticato di tenere traccia degli ordini che sono stati annullati.
[L06] La memorizzazione cambia durante l'emissione dell'evento
Nel NonceManager
contratto, quando il NonceIncreased
l'evento viene emesso, viene incrementato anche il nonce del mittente del messaggio.
L'esecuzione di più operazioni contemporaneamente può rendere la base di codice più difficile da ragionare, più soggetta a errori e può portare a trascurare o fraintendere le operazioni.
Per migliorare l'intenzionalità, la leggibilità e la chiarezza complessiva del codice, valutare la possibilità di aumentare il valore nonce prima di emettere l'evento.
Aggiornare: Risolto in richiesta pull # 63.
[L07] Metodologie di decodifica incoerenti potrebbero causare discrepanze nei risultati
Per supportare tutta la sua estensibilità e flessibilità, il Limit Order Protocol deve abitualmente gestire dati in byte dinamici e valori restituiti arbitrari da contratti esterni. Di conseguenza, il protocollo include un ArgumentsDecoder
libreria per convertire in modo più efficiente i valori dei byte dinamici in tipi di dati di base. Tuttavia, questa libreria non viene utilizzata esclusivamente e in alcuni casi abi.decode
viene utilizzato invece. Inoltre, alcuni contratti utilizzano abi coder v1
mentre altri stanno usando abi coder v2
. Il primo si comporta in modo più simile al ArgumentsDecoder
libreria, mentre quest'ultima esegue controlli aggiuntivi durante la decodifica.
L'uso incoerente di queste diverse metodologie di decodifica può provocare sottili discrepanze tra l'intenzione e il comportamento effettivo della base di codice.
Per esempio, la simulateCalls
la funzione utilizza solo il file ArgumentsDecoder.decodeBool
funzione. Se la simulateCalls
viene utilizzata per verificare le chiamate che verrebbero effettuate nella parte predicativa di un ordine, i suoi risultati potrebbero discostarsi da ciò che effettivamente accade quando vengono valutate le condizioni predicative, poiché vengono impiegate diverse metodologie di decodifica.
Quindi, ad esempio, se un predicato crea un external staticcall
a qualche funzione che restituisce a uint256
valore maggiore di uno rispetto a quello atteso bool
, la chiamata verrà annullata, poiché il valore restituito è decodificato con abi coder v2
'S abi.decode
che non accetterà valori come bool
. Tuttavia, se viene effettuata la stessa identica chiamata con simulateCalls
, allora sarà semplicemente contrassegnato come true
, perché decodeBool
tratta qualsiasi valore maggiore di zero come true
.
Per rendere simulateCalls
rispecchia completamente il comportamento delle chiamate ai predicati reali, valuta la possibilità di modificarla per utilizzarla abi.decode
.
Aggiornare: Risolto in richiesta pull # 82.
[L08] Manca la convalida dell'input
I fillOrderToWithPermit
ed fillOrderTo
funzioni del OrderMixin
contratto, nonché il fillOrderRFQToWithPermit
ed fillOrderRFQTo
funzioni del OrderRFQMixin
contratto, non convalidare il target
parametro dell'indirizzo.
Ciò consente a un utente di passare inavvertitamente l'indirizzo zero e, di conseguenza, bloccare gli asset che dovrebbe ricevere dopo aver completato un ordine.
Per garantire che gli utenti non blocchino accidentalmente i propri fondi, valuta la possibilità di convalidare che il file target
l'indirizzo non è uguale all'indirizzo zero nelle funzioni citate.
Aggiornare: Risolto in richiesta pull # 78.
[L09] Copertura del test unitario bassa
La copertura dei test unitari per l'intero progetto è pari a circa il 75%, con alcuni contratti che hanno una copertura particolarmente bassa.
Considerando l'importanza degli unit test per convalidare il codice e prevenire regressioni durante il refactoring e lo sviluppo di nuove funzionalità, incoraggiamo ad aumentare in modo significativo la copertura degli unit test almeno al 95% e a includere casi limite che coprano anche situazioni improbabili.
Aggiornare: Non riparato.
[L10] Documentazione inline fuorviante o incompleta
In tutta la codebase sono stati identificati alcuni casi di documentazione inline fuorviante e/o incompleta che dovrebbero essere corretti.
I seguenti sono esempi di documentazione inline ingannevole:
- Nel
ChainlinkCalculator
contratto, ilsinglePrice
della funzione Spec. Nat@notice
etichetta lo diceCalculates price of token relative to ETH scaled by 1e18
, ma in realtà il suo risultato è il APPREZZIAMO ofamount
gettoni ridimensionati da1e18
, dove l'oracolo potrebbe non riportare in termini di ETH (ad esempio per una coppia che non include ETH). - Nel
OrderRFQMixin
contratto, ilinvalidatorForOrderRFQ
della funzione Spec. Nat@return
etichetta è fuorviante, perché la virgoletta potrebbe non essere stata riempita affinché il rispettivo bit di invalidamento sia stato impostato. L'ordine può anche essere stato annullato. - In linea 147, 165e 188 of
OrderMixin.sol
, la specifica nazionale@param
i tag sono sgrammaticati. - In linea 20 of
ERC1155Proxy.sol
, le@notice
Il tag afferma che l'hash calcolato è il risultato dell'hashing del filefunc_733NCGU
funzione, dove dovrebbe essere ilfunc_301JL5R
funzione invece.
I seguenti sono esempi di documentazione in linea incompleta:
- Funzioni nel
AmountCalculator
contratto non descrivono nessuno dei parametri. - Nel
ChainlinkCalculator
contratto, ilsinglePrice
eddoublePrice
le funzioni non descrivono tutti i parametri. - Nel
ImmutableOwner
contratto, la variabile pubblica e il modificatore non hanno NatSpec. - Nel
InteractiveNotificationReceiver
contratto, ilnotifyFillOrder
la funzione non descrive nessuno dei parametri. - Nel
LimitOrderProtocol
contratto, ilDOMAIN_SEPARATOR
la funzione non ha NatSpec. - Eventi e mappature nel
NonceManager
non hanno NatSpec. - Nel
OrderRFQMixin
contratto,cancelOrderRFQ*
le funzioni non descrivono i valori restituiti. - Nel
OrderMixin
contratto, diverse funzioni mancano del NatSpec completo. - In linea 168 of
OrderMixin.sol
e in linea 71 ofOrderRFQMixin.sol
, manca il@dev
etichetta. - Funzioni nel
PredicateHelper
contratto non descrivono tutti i parametri.
Una chiara documentazione in linea è fondamentale per delineare le intenzioni del codice. Le discrepanze tra la documentazione in linea e l'implementazione possono portare a gravi malintesi su come ci si aspetta che il sistema si comporti. Valuta la possibilità di correggere questi errori per evitare confusione tra sviluppatori, utenti e revisori.
Aggiornare: Parzialmente risolto. Documentazione fuorviante affrontata in richiesta pull # 75 ed richiesta pull # 77.
Il team da 1 pollice afferma:
Abbiamo corretto i documenti fuorvianti. Il completamento dei documenti verrà effettuato in seguito.
[L11] Ordini DoS possibili quando si utilizzano gli hook
I OrderMixin
il contratto implementa funzionalità per soddisfare ordini di swap off-chain generici che potrebbero avere condizioni per il loro successo. Durante l'esecuzione dell'ordine, l'ordine può verificare le condizioni “predicate” predefinite prima di procedere con l'esecuzione.
Tuttavia, poiché queste condizioni predicative potrebbero prendere di mira la logica di qualsiasi contratto arbitrario, un produttore malintenzionato potrebbe indurre gli acquirenti a credere che un ordine si comporti correttamente e che sia valido quando lo controlla fuori catena, ma poi fallisce quando tenta di eseguire lo stesso ordine. sulla catena. Questo cambiamento nel comportamento dei predicati potrebbe essere effettuato anticipando qualche stato variabile da cui dipendono i predicati, esaminando il gas inviato o anche quali indirizzi sono coinvolti nella chiamata, o mediante qualche altra logica.
Inoltre, se il produttore ha definito a interazione durante lo scambio, le interactionTarget
il contratto potrebbe annullarsi o revocare l'indennità per impedire l'esecuzione corretta dell'ordine, portando essenzialmente allo stesso risultato dei predicati dannosi.
Anche se le risorse non saranno a rischio, gli utenti o i bot che trovano un ordine favorevole avranno l’onere maggiore di cercare di identificare questo tipo di ordini di spam che in superficie possono sembrare legittimi. Nel caso in cui non riescano a identificare questo tipo di ordini, incorreranno nei costi del gas sprecato. Per ridurre la quantità di ordini di spam, valuta la possibilità di limitare gli obiettivi disponibili per questi hook. Considera anche la possibilità di avvisare gli utenti di questa possibilità prima di tentare di evadere gli ordini.
Aggiornare: Non riparato. Il team da 1 pollice afferma:
Lo gestiamo sul nostro backend e penseremo a come avvisare i possibili acquirenti del problema.
[L12] L'arrotondamento può essere sfavorevole taker
Nel OrderMixin
ed OrderRFQMixin
contratti, quando un ordine viene eseguito e l'acquirente fornisce solo a makingAmount
or takingAmount
importo, il protocollo tenta di calcolare l'importo di contropartita dello swap.
Ci sono due problemi con questi calcoli, il primo è che non esiste documentazione o logica che limiti il numero di decimali che i parametri di importo dovrebbero utilizzare, di cui abbiamo parlato Presupposti decimali non documentati problema.
La seconda questione è che, nel corso di questi calcoli, il protocollo gira a favore del produttore. Il problema dell'arrotondamento può essere notevolmente aggravato quando i presupposti decimali impliciti vengono violati, ma anche quando tutto rispetta i termini previsti, l'arrotondamento avverrà con importi piccoli e dispari.
Considera la possibilità di consentire all'acquirente di specificare un importo minimo di makerAsset
bene che sono disposti a ricevere insieme ad un importo massimo di takerAsset
asset che sono disposti a scambiare, in modo che l’accettazione di qualsiasi arrotondamento sia più esplicita.
Aggiornare: Non riparato. Il team da 1 pollice afferma:
L'importo della soglia dovrebbe essere sufficiente per la protezione dell'acquirente.
[L13] Gestione degli ordini contraddittoria in mancanza di parametri
Nel OrderMixin
contratto, il fillOrderTo
la funzione effettua chiamate interne al _callGetMakerAmount
ed _callGetTakerAmount
funziona ogni volta che si tenta un riempimento e il makingAmount
oppure takingAmount
i parametri sono zero, rispettivamente, o se il makingAmount
il valore è maggiore di remainingMakerAmount
valore.
I _callGetMakerAmount
ed _callGetTakerAmount
le chiamate porteranno a reversioni se l'ordine non è stato creato con il getMakerAmount
or getTakerAmount
parametri rispettivamente e viene eseguito un riempimento parziale.
An commento in linea a fianco _callGetMakerAmount
e commento in linea a fianco _callGetTakerAmount
affermare che "sono consentiti solo riempimenti interi" se l'ordine non è stato creato con getMakerAmount
or getTakerAmount
parametri.
Tuttavia, esistono percorsi di codice per i quali ciò non si applica, poiché tali percorsi non controllano il file length
s di entrambi getMakerAmount
ed getTakerAmount
parametri.
specificamente, Quando un taker
specifica a takerAmount
valore per un ordine che ha solo a getMakerAmount
, a meno che non chiami a getMakerAmount
restituisce un importo maggiore di remainingMakerAmount
, è possibile eseguire un riempimento parziale in contraddizione con la documentazione in linea.
Ciò lascia poco chiara l'intenzionalità di tali percorsi di codice. Se questo è il comportamento previsto, valuta la possibilità di modificare la documentazione incorporata in modo che sia più esplicita. Se si tratta di un comportamento involontario, valuta la possibilità di controllare sempre la lunghezza di entrambi i file getMakerAmount
e la getTakerAmount
parametri contemporaneamente in modo che l'implementazione rafforzi il comportamento descritto dalla documentazione in linea.
Aggiornare: Risolto in richiesta pull # 79.
[L14] Utilizzo delle chiamate Chainlink deprecate
I ChainlinkCalculator
contract è destinato ad essere utilizzato per interrogare gli oracoli di Chainlink. Lo fa effettuando chiamate al loro latestTimestamp
ed latestAnswer
metodi, entrambi sono stati deprecati. Infatti i metodi non sono più presenti nelle API degli aggregatori Chainlink a partire dalla versione tre.
Per evitare potenziali future incompatibilità con gli oracoli di Chainlink, considera l'utilizzo del file latestRoundData
metodo invece.
Aggiornare: Risolto in richiesta pull # 67.
Note e informazioni aggiuntive
[N01] Interfacce non importate
I AggregatorInterface
sembra essere un sottoinsieme del codice copiato da ChainLink
il repository di codice pubblico di. L'interfaccia completa è inclusa in ChainLink
il pacchetto npm del contratto di.
Quando possibile, per ridurre il rischio di discrepanze tra le interfacce e i problemi che ne derivano, anziché ridefinire e/o riscrivere le interfacce di un altro progetto, prendere in considerazione l'utilizzo delle interfacce installate tramite i pacchetti npm ufficiali.
Aggiornare: Risolto in richiesta pull # 66.
[N02] Dipendenze del progetto obsolete
Durante l'installazione del dipendenze del progetto, NPM avverte che uno dei pacchetti installati, Highlight
, "non sarà più supportato né riceverà aggiornamenti di sicurezza in futuro".
Anche se è improbabile che questo pacchetto possa causare un rischio per la sicurezza, considerare l'aggiornamento della dipendenza che utilizza questo pacchetto a una versione mantenuta.
Aggiornare: Risolto in richiesta pull # 64.
[N03] Le chiamate esterne ai metodi di visualizzazione non sono chiamate statiche
Nella maggior parte del codice base, il protocollo effettua esplicitamente chiamate esterne tramite OpenZeppelin functionStaticCall
metodo per limitare la possibilità di cambiamenti di stato quando non sono previsti o non desiderabili. Tuttavia, nel ChainlinkCalculator
contratto, nonostante l'intenzione di effettuare chiamate esterne solo a view
metodi sugli oracoli Chainlink, le chiamate esterne nel file singlePrice
ed doublePrice
le funzioni non vengono eseguite tramite esplicito staticcall
s.
Anche se non abbiamo identificato alcun problema di sicurezza immediato derivante da ciò, per ridurre la superficie di attacco, migliorare la coerenza e chiarire l'intento, prendi in considerazione l'utilizzo di espliciti staticcall
s, per tutte le chiamate esterne a view
funzioni in ChainlinkCalculator
contrarre.
Aggiornare: Non riparato. Il team da 1 pollice afferma:
Riteniamo che la complicazione della sintassi annulli i miglioramenti nella coerenza.
[N04] Non fallire in anticipo con ordini non validi
Nel OrderMixin
contratto, il fillOrderTo
la funzione gestisce la condizione speciale quando un ordine non è stato precedentemente inviato (remainingMakerAmount == 0
), ma non gestisce esplicitamente la condizione in cui l'ordine non è più valido (remainingMakerAmount == 1
).
In quest’ultimo scenario, la funzione verrà ripristinata, ma solo dopo aver bruciato quantità di gas non banali. Per chiarire l'intento, aumentare la leggibilità e ridurre il consumo di gas, prendi in considerazione la gestione esplicita dello scenario di ordine non valido verso l'inizio della funzione.
Aggiornare: Risolto in richiesta pull # 68.
[N05] Contratti di supporto non contrassegnati come astratti
In Solidità, la parola chiave abstract
viene utilizzato per contratti che non sono contratti funzionali di per sé o non sono destinati a essere utilizzati come tali. Invece, abstract
i contratti vengono ereditati da altri contratti nel sistema per creare contratti funzionali autonomi.
In tutto il codice base sono presenti esempi di contratti di supporto che non sono contrassegnati come astratti, nonostante non siano destinati a essere distribuiti da soli. Ad esempio, il AmountCalculator
, ChainlinkCalculator
, ImmutableOwner
, NonceManager
e PredicateHelper
i contratti sono tutti costituiti da un insieme base di funzioni destinate ad essere utilizzate dai contratti ereditari.
Valuta la possibilità di contrassegnare i contratti di aiuto come abstract
per indicare chiaramente che sono progettati esclusivamente per aggiungere funzionalità ai contratti che li ereditano.
Aggiornare: Non riparato. Il team da 1 pollice afferma:
Questi aiutanti possono essere schierati separatamente. Vengono ereditati solo per il risparmio di gas.
[N06] Ordine delle funzioni incoerente
In tutta la base di codice, l'ordinamento delle funzioni generalmente segue il metodo ordine consigliato nella Solidity Style Guide, che è: constructor
, fallback
, external
, public
, internal
, private
.
Tuttavia, nel OrderMixin
contratto, il public
checkPredicate
la funzione si discosta dalla guida di stile, dividendo in due la external
funzioni.
Per migliorare la leggibilità complessiva del progetto, prendere in considerazione la standardizzazione dell'ordinamento delle funzioni in tutto il codice base, come raccomandato dalla Solidity Style Guide.
Aggiornare: Risolto in richiesta pull # 69.
[N07] Flusso di riempimento dell'ordine incoerente
I OrderMixin
ed RFQOrderMixin
Entrambi i contratti gestiscono l'esecuzione degli ordini firmati, ma il flusso generale degli ordini tra i due contratti è incoerente.
OrderMixin
'S fillOrderTo
la funzione segue questo flusso generale (pseudo-codice):
if ((takingAmount == 0) == (makingAmount == 0))
else if (takingAmount == 0)
else (handle makingAmount == 0) THEN swapTokens
Mentre RFQOrderMixin
è analogo fillOrderRFQTo
la funzione segue questo flusso (pseudo-codice):
if (takingAmount == 0 && makingAmount == 0)
else if (takingAmount == 0)
else if (makingAmount == 0)
else revert THEN swapTokens
Non ci sono approfondimenti dalla documentazione sul motivo per cui il primo condizionale in ciascuna di queste due funzioni differisce o perché takingAmount
ed makingAmount
non possono essere entrambi zero in quest'ultima funzione. Inoltre, il caso in cui sia a makingAmount
e takingAmount
sono forniti è molto più facile ragionare nel file fillOrderRFQTo
funzione, poiché viene gestita chiaramente nel finale else
blocco.
Per chiarire l'intento e aumentare la leggibilità complessiva del codice, valuta la possibilità di standardizzare il flusso generale degli ordini tra questi due contratti o di documentare esplicitamente il motivo per cui esistono le differenze.
Aggiornare: Non riparato. Il team da 1 pollice afferma:
Ciò è dovuto alle funzioni di determinazione del prezzo personalizzate negli ordini limite. Da
getMakerAmount
può potenzialmente differire sostanzialmente dagetTakerAmount
, abbiamo pensato che fosse meglio non impostare l'opzione predefinita per l'acquirente poiché probabilmente lo confonderebbe nei casi in cui i getter saranno diversi.
[N08] I messaggi di errore sono formattati in modo incoerente o fuorvianti
In tutta la base di codice, il require
ed revert
è stato riscontrato che i messaggi di errore, che hanno lo scopo di avvisare gli utenti delle particolari condizioni che causano il fallimento di una transazione, sono formattati in modo incoerente.
Ad esempio, ciascuno dei messaggi di errore sulle righe 85 di OrderMixin.sol
, 16 di ERC721ProxySafe.sol
e 26 di Permitable.sol
impiegare uno stile diverso.
Inoltre, alcuni messaggi di errore sono fuorvianti:
I messaggi di errore hanno lo scopo di avvisare gli utenti in merito a condizioni di errore, quindi dovrebbero fornire informazioni sufficienti per poter apportare le correzioni appropriate per interagire con il sistema. I messaggi di errore non informativi danneggiano notevolmente l'esperienza complessiva dell'utente, riducendo così la qualità del sistema. Inoltre, i messaggi di errore formattati in modo incoerente possono creare confusione inutile. Pertanto, valuta la possibilità di rivedere l'intera codebase per assicurarti che ogni require
ed revert
L'istruzione contiene un messaggio di errore formattato in modo coerente, accurato, informativo e facile da usare.
Aggiornare: Parzialmente fissato in richiesta pull # 81.
[N09] Uso incoerente di variabili di ritorno con nome
C'è un uso incoerente delle variabili di ritorno denominate in OrderMixin
contrarre. Alcune funzioni restituiscono variabili denominate, altri restituire valori espliciti, e altri dichiarare una variabile di ritorno denominata ma sovrascriverla con un'istruzione return esplicita.
Prendere in considerazione l'adozione di un approccio coerente per restituire i valori in tutta la codebase rimuovendo tutte le variabili di ritorno denominate, dichiarandole esplicitamente come variabili locali e aggiungendo le necessarie istruzioni di ritorno ove appropriato. Ciò migliorerebbe sia l'esplicitezza che la leggibilità del codice e potrebbe anche aiutare a ridurre le regressioni durante i futuri refactoring del codice.
Aggiornare: Risolto in richiesta pull # 73.
[N10] Il calcolo dell'hash dell'ordine non è aperto all'API
I external
funzioni remaining
, remainingRaw
ed remainingsRaw
tutti si aspettano un hash dell'ordine per un'operazione riuscita.
Tuttavia, la funzione di supporto _hash
, che restituisce l'hash di un ordine, ha private
visibilità. Ciò significa che gli utenti dovranno impacchettare manualmente parti degli ordini e stringhe di dominio per ottenere l'hash di un ordine.
Per evitare potenziali errori durante il calcolo degli hash degli ordini e fornire agli utenti un metodo per generare il rispettivo hash di un ordine, valuta la possibilità di estendere la visibilità degli hash degli ordini _hash
funzione a public
e rifattorizzare il nome in hash
per essere coerente con il resto del codice.
Aggiornare: Risolto in richiesta pull # 74.
[N11] Sovraccarico semantico della mappatura
I _remaining
mappatura nel OrderMixin
Il contratto è semanticamente sovraccarico per tenere traccia dello stato degli ordini e della quantità rimanente di risorse disponibili per tali ordini.
I tre stati che può assumere sono:
0
: L'hash dell'ordine non è stato ancora visto.1
: L'ordine è stato annullato o completamente evaso.- Qualsiasi
uint
più largo di1
: Il restomakerAmount
disponibile per essere compilato nell'ordine plus1
.
Questo sovraccarico semantico richiede l'avvolgimento e l'annullamento del confezionamento di questo valore durante lookup
, cancellation
, initialization
e storage
.
Il sovraccarico semantico e la logica necessaria per abilitarlo possono essere soggetti a errori e possono rendere la base di codice più difficile da comprendere e su cui ragionare, potrebbero anche aprire la porta a regressioni nei futuri aggiornamenti del codice.
Per migliorare la leggibilità del codice, valuta la possibilità di monitorare lo stato di completamento degli ordini in una mappatura separata.
Aggiornare: Non riparato. Il team di 1 pollice ha affermato che una soluzione aumenterebbe i costi del gas per il fillOrder
funzione.
[N12] Gli ordini con permesso consentono chiamate a contratti arbitrari
I OrderMixin
il contratto eredita il Permitable
contratto per consentire l'esecuzione dell'ordine di una singola transazione con asset che lo accettano permit
chiede di modificare le indennità.
Tuttavia, la chiamate al Permitable
contratto non convalidano se l'obiettivo è una risorsa consentita e nemmeno se è una risorsa, il che potrebbe consentire a un utente malintenzionato di passare l'indirizzo di un contratto arbitrario che potrebbe eseguire un'altra chiamata prima del completamento dell'esecuzione dell'ordine.
Anche se il contratto lo è protetto contro il rientro, è sempre consigliabile ridurre la superficie di attacco e impedire il richiamo di contratti esterni durante l'esecuzione. Prendi in considerazione la possibilità di limitare la risorsa coinvolta nel permesso alle risorse coinvolte nell'ordine o a una lista bianca di risorse per il protocollo.
Aggiornare: Non riparato. Il team da 1 pollice afferma:
OrderMixin
in realtà non ha informazioni sui token effettivi comemakerAsset
edtakerAsset
a volte sono proxy o altri contratti intermedi e le informazioni sui token effettivi sono archiviate in alcuni byte arbitrari. Quindi non esiste un modo praticabile per limitare quale risorsapermit
viene chiamato.
[N13] solhint
non viene mai riattivato
In tutto il codice base, ce ne sono un paio solhint-disable
dichiarazioni, in particolare quelle on line 23 e in linea 41 of RevertReasonParser.sol
, che non terminano con solhint-enable
.
A favore dell'esplicitezza e dell'essere il più restrittivi possibile quando si disabilita solhint
, considera l'utilizzo solhint-disable-line
or solhint-disable-next-line
invece, simile alla linea 16 dello stesso file.
Aggiornare: Risolto in richiesta pull # 72.
[N14] Errori di battitura
La base di codice contiene i seguenti errori di battitura:
Inoltre il progetto README
(fuori dall'ambito di questo controllo) contiene i seguenti errori di battitura:
Valuta la possibilità di correggere questi errori di battitura per migliorare la leggibilità del codice.
Aggiornare: Risolto in richiesta pull # 71 ed richiesta pull # 77.
[N15] Utilizzo di uint
invece di uint256
Per favorire l'esplicitezza, tutte le istanze di uint
dovrebbe essere dichiarato come uint256
. In particolare, quelli in for
loop sulle linee 98 ed 119 of OrderMixin.sol
e linee 16 ed 30 of PredicateHelper.sol
.
Aggiornare: Risolto in richiesta pull # 70.
Conclusioni
Sono stati rilevati 3 problemi di elevata gravità. Sono state proposte alcune modifiche per seguire le migliori pratiche e ridurre la potenziale superficie di attacco.
- &
- 7
- Chi siamo
- accesso
- Secondo
- Il mio account
- operanti in
- Legge
- azioni
- aggiuntivo
- indirizzo
- Vantaggio
- Tutti
- Consentire
- già
- Sebbene il
- importi
- .
- api
- approccio
- argomenti
- in giro
- attività
- Attività
- revisione
- Back-end
- Inizio
- essendo
- MIGLIORE
- best practice
- Po
- bots
- costruire
- chiamata
- che
- casi
- Causare
- chainlink
- il cambiamento
- verifica
- Controlli
- codice
- complesso
- condizione
- confusione
- costruzione
- contiene
- contratto
- contratti
- Correzioni
- Costi
- potuto
- Coppia
- Creatore
- Valuta
- Corrente
- dati
- affare
- Denial of Service
- distribuzione
- Design
- sviluppatori
- Mercato
- DID
- differire
- diverso
- dominio
- doppio
- dinamico
- Presto
- bordo
- incoraggiare
- particolarmente
- ETH
- Evento
- eventi
- qualunque cosa
- esempio
- exchange
- previsto
- esperienza
- Sfruttare
- Caratteristiche
- campi
- Infine
- Nome
- Fissare
- Flessibilità
- flusso
- seguire
- essere trovato
- pieno
- function
- fondi
- futuro
- gioco
- GAS
- Generale
- Dare
- grande
- guida
- Manovrabilità
- hash
- hashing
- avendo
- Aiuto
- Alta
- vivamente
- Come
- HTTPS
- IBRIDO
- identificare
- Impact
- realizzare
- importante
- importazione
- incluso
- Compreso
- Aumento
- è aumentato
- info
- informazioni
- Infrastruttura
- intuizioni
- intento
- interesse
- Interfaccia
- coinvolto
- sicurezza
- IT
- grandi
- superiore, se assunto singolarmente.
- portare
- principale
- Biblioteca
- Limitato
- linea
- Liquidità
- elencati
- elenchi
- locale
- guardò
- ricerca
- maggiore
- creatore
- Fare
- Rappresentanza
- MemPool
- specchio
- modello
- maggior parte
- Più popolare
- cioè
- Nuove funzionalità
- non fungibili
- gettoni non fungibili
- ufficiale
- aprire
- Operazioni
- Opzione
- oracolo
- minimo
- ordini
- Altro
- proprietario
- Cartamodello
- Popolare
- presenti
- prevenzione
- prezzo
- prezzi
- un bagno
- processi
- progetto
- progetti
- protezione
- protocollo
- fornire
- fornisce
- delega
- la percezione
- pubblicare
- Acquista
- qualità
- aumentare
- Realtà
- ridurre
- fiducia
- rapporto
- Report
- deposito
- Requisiti
- REST
- Risultati
- problemi
- recensioni
- Rischio
- round
- Correre
- sdk
- problemi di
- Servizi
- set
- condiviso
- azioni
- spostamento
- simile
- Un'espansione
- piccole
- smart
- Smart Contract
- So
- solidità
- carne in scatola
- in particolare
- Spendere
- Spot
- inizia a
- Regione / Stato
- dichiarazione
- stati
- Stato dei servizi
- conservazione
- style
- presentata
- il successo
- di successo
- Con successo
- supporto
- supportato
- superficie
- Interruttore
- sistema
- Target
- test
- Testing
- test
- Attraverso
- per tutto
- tempo
- insieme
- token
- Tokens
- pista
- Tracking
- delle transazioni
- Affidati ad
- unico
- Aggiornamenti
- us
- usabilità
- USD
- USDT
- utenti
- utilità
- APPREZZIAMO
- Visualizza
- visibilità
- aspettare
- Che
- whitelist
- entro
- senza
- Lavora
- valore
- zero