Recentemente, Uniswap Lab ha annunciato ufficialmente i progressi nello sviluppo della prossima generazione di AMM Uniswap V4 e ha rilasciato il white paper e il repository del codice. Questa volta, il white paper di V4 è di sole 3 pagine. Il motivo è che V4 non apporta molte modifiche alla logica dell'algoritmo principale di AMM, ma aggiunge alcune nuove funzionalità basate su V3 per soddisfare le esigenze di più scenari. SharkTeam utilizzerà il codice attualmente open source per vedere quali nuove funzionalità apporta V4 e analizzare le migliori pratiche applicative per agganciare le importanti funzionalità lanciate da V4.
1. La differenza tra V4 e V3
1.1 AMM
A livello di algoritmo AMM, Uniswap V4 non ha modificato V3 e utilizza ancora un algoritmo di liquidità basato sul prodotto costante x*y=k.
In Uniswap V3, ciascuna coppia di trading può avere 4 pool (originariamente 3, e successivamente è stato aggiunto un nuovo pool da 1 bp), che rappresentano pool con tassi di commissione rispettivamente dello 0,01%, 0,05%, 0,3% e 1%. Questi pool corrispondono al tick anche gli spazi sono diversi Quando crei un pool, puoi scegliere solo uno qualsiasi di questi 4 tipi.
In Uniswap V4, ciascuna coppia di trading può teoricamente avere un numero qualsiasi di pool e anche la tariffa di ciascuna pool può avere qualsiasi valore e anche lo spazio di spunta di questi pool può essere qualsiasi valore.
Ciò comporta anche un problema: la liquidità delle coppie di trading in Uniswap V4 sarà frammentata, quindi è necessario un router/aggregatore più efficace per aiutare gli utenti a trovare il percorso di trading ottimale.
1.2 Ganci
Gli hook sono un insieme di contratti sviluppati da terze parti o da funzionari di Uniswap Quando si crea un pool, il pool può scegliere di vincolare un hook. Successivamente, in fasi specifiche della transazione, il pool chiamerà automaticamente il contratto Hook ad esso legato. Uniswap V4 definisce queste fasi in cui è possibile eseguire il codice del contratto hook:
prima di Inizializzare
dopoInizializzare
prima di modificare la posizione
dopoModificaPosizione
prima dello scambio
dopoScambio
prima di donare
dopoDona
Ciò significa che il contratto hook può essere richiamato prima e dopo l'inizializzazione del pool, l'aggiunta/rimozione di liquidità, lo scambio, la donazione e altre operazioni.
Il contratto Hook deve specificare esplicitamente quali delle fasi di cui sopra devono essere eseguite e il pool deve sapere se il corrispondente Hook deve essere eseguito in una determinata fase Per risparmiare gas, questi flag non sono memorizzati nel contratto , ma richiedono che l'Hook utilizzi un indirizzo specifico per indicare. Lo specifico codice di giudizio è il seguente:
Si può vedere che i primi 8 bit dell'indirizzo dell'Hook non vengono utilizzati come flag per contrassegnare se l'Hook deve essere eseguito in una fase specifica.
Pertanto, gli sviluppatori Hook devono generare indirizzi che soddisfino i requisiti del pool durante la distribuzione dei contratti. Per raggiungere questo obiettivo, in genere è necessario utilizzare Create2 + il calcolo del Salt casuale.
Quello che segue è un esempio di esecuzione dell'Hook nel white paper:
Si può vedere che prima e dopo l'esecuzione dello scambio, il pool controllerà innanzitutto se il corrispondente hook del pool ha il flag corrispondente attivato. Se è attivato, verrà automaticamente richiamata la funzione corrispondente del contratto Hook.
1.3 Coefficiente tariffario dinamico
Oltre ad eseguire il codice in una fase specifica, Hook può anche determinare il tasso della commissione di swap e il tasso di prelievo di un determinato pool. Il tasso di prelievo si riferisce al tasso che gli utenti devono pagare a Hook quando rimuovono la liquidità. Inoltre, Hook può anche specificare per sé una parte della commissione di swap.
Quando crei un pool, devi utilizzare i primi 4 bit del parametro tariffa (uint24) per indicare se questo pool utilizza commissioni dinamiche e se abilitare la commissione di scambio hook e la commissione di prelievo:
Se la commissione dinamica è abilitata, il pool chiamerà il contratto Hook per ottenere il rapporto della commissione di swap corrente prima di ogni scambio. Il contratto Hook deve implementare la funzione getFee() per restituire il rapporto della commissione di swap corrente.
Gli hook rendono Uniswap V4 una piattaforma per sviluppatori e offrono ad AMM maggiori possibilità. Alcune funzioni che possono essere implementate utilizzando gli Hooks includono TWAMM (market maker automatico ponderato nel tempo), Limit Order (ordine limite), reinvestimento LP, ecc., che verranno introdotte in dettaglio nei capitoli successivi.
1.4 Contratto Singleton
Ogni volta che viene creato un nuovo pool in Uniswap V3, è necessario implementare un nuovo contratto, che consuma molto gas. Tuttavia, in realtà, i codici utilizzati da questi pool sono gli stessi, ma i parametri di inizializzazione sono diversi. Uniswap V4 introduce il contratto Singleton per gestire tutti i pool. In questo modo, la creazione di un nuovo pool non richiede più l'implementazione di un nuovo contratto, risparmiando gas per l'implementazione dei contratti.
Inoltre, il vantaggio dell'utilizzo del contratto Singleton è che può ridurre il trasferimento di token durante il processo di transazione. Poiché tutti i pool sono nello stesso contratto, gli scambi tra pool possono essere completati direttamente all'interno del contratto. pool swap Sarà necessario trasferire il token tra diversi pool, il che aumenterà il gas.
Allo stesso tempo, nella V4, tutti i pool utilizzano lo stesso contratto e anche la contabilità dei token all'interno del contratto è stata semplificata per ogni token contabilizzando per token invece che per pool. In questo modo, se si desidera utilizzare i prestiti flash A anche un gran numero di token sarà più conveniente.
1.5 estensione
Per facilitare l'integrazione di Hook e altri contratti, il contratto V4 aggiunge una funzione extload, in modo che tutti gli stati interni del contratto diventino leggibili esternamente e lo stato di tutti i pool sarà completamente trasparente verso l'esterno.
1.6 Contabilità Flash
Al fine di ridurre i trasferimenti di token tra pool swap, V4 utilizza anche un metodo chiamato Flash Accounting per standardizzare i processi di swap, aggiungere/rimuovere liquidità/prestito flash in un processo simile ai prestiti flash:
(1) L'utente ottiene un blocco
(2) L'utente esegue qualsiasi operazione, come lo scambio in più pool, l'aggiunta/rimozione di liquidità o il prestito di token dal pool tramite prestiti flash
(3) I trasferimenti di token generati da tutte le operazioni dell'utente verranno registrati nella serratura.
(4) Dopo che tutte le operazioni sono state completate, l'utente può portare via il gettone ottenuto e allo stesso tempo deve pagare il gettone che deve pagare registrato nella serratura.
Questi processi devono avvenire all'interno di una transazione.
In questo modo, se una transazione richiede uno scambio tra più pool, durante il regolamento saranno necessari solo due trasferimenti. Ad esempio, in uno swap come ETH->USDC-BTC, USDC come token intermedio non richiede alcun trasferimento.
1.7 ERC1155 menta/brucia
Flash Accounting può ridurre i trasferimenti di token di scambio nella stessa transazione. Utilizzando i token ERC1155, può ridurre ulteriormente i trasferimenti di token in più transazioni.
V4 ti consente di salvare i tuoi token nel contratto V4 tramite ERC1155 mint, in modo da poter utilizzare questi token in più transazioni senza dover trasferire ogni volta i token nel contratto V4.
Utilizza la masterizzazione ERC1155 per ritirare i token archiviati nel contratto V4.
ERC1155 è adatto agli utenti che scambiano o aggiungono/rimuovono frequentemente liquidità. Questi utenti possono archiviare i token di uso comune direttamente nel contratto V4, il che può ridurre il sovraccarico di gas dei trasferimenti di token.
2. Esempi di migliori pratiche negli Hooks
2.1 TWAMM (Market Maker automatizzato ponderato nel tempo)
Alice vuole acquistare ether per un valore di 100 milioni di dollari sulla blockchain. L'esecuzione di un ordine di queste dimensioni sulle piattaforme esistenti di market maker automatizzati (AMM) come Uniswap sarebbe proibitivamente costosa poiché queste piattaforme probabilmente addebiterebbero ad Alice commissioni elevate per impedirle di utilizzare informazioni privilegiate per ottenere prezzi migliori.
Per ottenere un prezzo migliore, la soluzione migliore per Alice è quella di suddividere manualmente l'ordine in diversi sottoordini più piccoli ed eseguirli in modo incrementale nell'arco di poche ore. L’idea è di dare al mercato abbastanza tempo per rendersi conto di non avere informazioni privilegiate e quindi offrirgli un prezzo migliore. Tuttavia, anche se invia numerosi sottoordini di dimensioni maggiori, ciascun sottoordine avrà comunque un impatto significativo sul prezzo, pur essendo vulnerabile a un "attacco sandwich" da parte di trader ostili.
TWAMM risolve questo problema conducendo transazioni per conto di Alice. Suddivide il suo ordine in un numero infinito di piccoli ordini virtuali per garantire un'esecuzione regolare nel tempo. Allo stesso tempo, TWAMM utilizza la speciale relazione matematica del protocollo AMM integrato per allocare i costi del gas tra questi ordini virtuali. Poiché TWAMM elabora le transazioni tra blocchi, non è vulnerabile agli "attacchi sandwich".
Nel complesso, TWAMM fornisce ad Alice un modo più efficiente per condurre transazioni su larga scala, evitando commissioni elevate e potenziali manipolazioni del mercato.
2.1.1 Principio
TWAMM dispone di un'AMM integrata, che non è diversa dalle altre AMM. Gli utenti possono effettuare direttamente transazioni spot tramite questa AMM e possono anche aggiungervi liquidità. Tuttavia, TWAMM dispone anche di due pool di ordini TWAP, che vengono utilizzati per eseguire ordini TWAP in due direzioni. Quando l'utente invia l'ordine, specifica il numero e la durata dell'input del token della transazione e TWAMM inserirà l'ordine. stessa direzione della transazione nel pool corrispondente ed eseguire automaticamente le transazioni in base alla velocità di transazione specificata. Quando l'ordine dell'utente è completamente eseguito, l'utente può prelevare il token ottenuto dalla transazione. Naturalmente, prima che l'ordine dell'utente venga eseguito, l'utente può anche annullare l'ordine in anticipo o modificare il numero di token necessari per l'ordine.
In Ethereum, i contratti intelligenti possono essere attivati solo da transazioni avviate attivamente dall'indirizzo EOA, ma non possono essere eseguiti automaticamente. Pertanto, TWAMM ha bisogno che l'account EOA invii transazioni regolarmente per regolare i token da scambiare nel suo pool di ordini, che richiede un conto keeper per eseguire queste transazioni.
Naturalmente, puoi anche consentire a TWAMM di regolare automaticamente il pool di ordini ogni volta che un utente interagisce con esso, eliminando così il sovraccarico del keeper. Questo è anche un modo comune per i protocolli DeFi di elaborare i dati in streaming.
2.1.2 Perché questo modello di transazione è difficile da attaccare con un sandwich?
Questo attacco è difficile da implementare perché il timestamp in un blocco non cambierà. L'attaccante deve aumentare il prezzo del pool nell'ultima transazione di un blocco, in modo che la transazione TWAMM nel blocco successivo venga influenzata. Ciò richiede che l’attacco sandwich avvenga in più blocchi, il che comporterà senza dubbio grandi rischi per l’attaccante, perché altri arbitraggisti potrebbero intervenire nel mezzo, causando perdite all’attaccante.
Allo stesso tempo, a causa dell’esistenza di arbitraggisti, tale manipolazione dei prezzi è destinata a essere insostenibile. A causa delle caratteristiche dell’ordine TWAP, non verranno scambiati troppi token in un breve periodo di tempo, quindi le perdite devono essere limitate. la maggior parte dei casi.
2.1.3 Flusso di lavoro TWAMM nella V4
(1) Questo Hook mantiene due pool di ordini TWAP, che rappresentano rispettivamente gli ordini TWAP in due direzioni di transazione.
(2) Gli utenti possono inviare ordini TWAP tramite questo Hook. Devono specificare il token, la quantità e la durata della transazione.
(3) Questo Hook viene registrato beforeSwap e beforeModifyPosition. Questo Hook verrà attivato ogni volta che l'utente negozia o modifica una posizione.
(4) Dopo essere stato attivato, Hook è responsabile della liquidazione dei due pool di ordini TWAP
(5) Gli utenti possono anche attivare manualmente il regolamento in qualsiasi momento
(6) Gli utenti possono annullare o modificare il numero di token nell'ordine TWAP
2.1.4 Spiegazione dettagliata degli esempi
TWAMM registra tre fasi per eseguire chiamate logiche di hook TWAMM viene inizializzato prima che il pool venga inizializzato e questo hook viene attivato ogni volta che l'utente negozia o modifica una posizione.
Gli utenti possono chiamare manualmente la funzione sendOrder in TWAMM per inviare l'ordine di cui hanno bisogno per eseguire il contratto.
Dopo che l'utente ha aggiunto l'ordine che deve eseguire nel contratto, l'ordine verrà eseguito automaticamente ogni volta che il pool esegue operazioni di scambio e modifica della posizione.
Ogni volta che un utente chiama la funzione di scambio di v4 per scambiare o modificare la funzione Posizione per modificare una posizione, verrà attivata la funzione di esecuzione in TWAMM e la funzione interna _executeTWAMMOrders verrà chiamata nella funzione per continuare l'esecuzione dell'ordine precedentemente incompleto.
_executeTWAMMOrders funzione
Quanto sopra è il processo di esecuzione dell'aggiornamento dell'ordine Una volta completata l'esecuzione, l'attuale tempo di esecuzione dell'ordine twamm verrà aggiornato.
2.2 Ordine Limite
A differenza degli ordini di mercato, che vengono eseguiti immediatamente all'ultimo prezzo di mercato, gli ordini limite vengono eseguiti non appena viene raggiunto un prezzo predeterminato. La maggior parte dei DEX basati su market maker automatizzati (AMM) scelgono il sistema degli ordini di mercato per impostazione predefinita. Semplice e di facile comprensione per i nuovi arrivati. Gli ordini di mercato vengono eseguiti o falliscono a causa di parametri come l'impatto massimo del prezzo. In un ordine limite, l'ordine verrà eseguito solo quando il prezzo dell'asset raggiunge il prezzo limite, altrimenti l'ordine rimarrà aperto.
Ad esempio, supponiamo che ETH venga attualmente scambiato nel pool ETH/DAI a 1 ETH = 1500 DAI. Gli utenti possono effettuare un ordine di take profit, il cui contenuto principale è "Se 1 ETH = 2000 DAI, vendi tutti i miei ETH". Se questo prezzo viene raggiunto, l’ETH degli utenti verrà automaticamente scambiato con DAI completamente on-chain in modo decentralizzato.
Nelle versioni precedenti di Uniswap, gli ordini limite erano praticamente impossibili. La maggior parte degli AMM consentono solo acquisti e vendite sul mercato. Nella versione V4, grazie alle potenti funzionalità e alla scalabilità degli hook, esiste una base per l'implementazione degli ordini limite nella v4.
2.2.1 Principio
Il principio di progettazione dell'ordine limite è più semplice di quello del twamm. Attualmente sono stati implementati ordini limite per l'aggiunta di liquidità e sarà più semplice implementare ordini limite per le transazioni.
Poiché tickLower e tickUpper esistono nella v4 e, in base ai cambiamenti nella situazione commerciale del pool, inferiore e superiore cambieranno. Quando gli utenti aggiungono liquidità, non vogliono aggiungerla al prezzo corrente. In questo caso, possono utilizzarli il gancio dell'ordine limite per soddisfare questo requisito, imposta il prezzo corrispondente nel gancio. Dopo ogni scambio, il gancio giudicherà il prezzo del pool corrente. Se viene raggiunto il prezzo impostato, verrà aggiunta la liquidità corrispondente per ottenere reddito.
2.2.2 Flusso di lavoro degli ordini con limite nella V4
1. Il limite mantiene più epoche come ordini limite per diversi ribassi e direzioni di negoziazione.
2. Attraverso questo hook, l'utente invia il prezzo inferiore e la direzione della transazione e aggiunge l'ordine limite al contratto.
3. Questo Hook si registra dopo lo Swap e viene attivato solo quando il prezzo cambia dopo la fine di ogni swap.
4. Dopo essere stato attivato, Hook verifica l'intervallo di prezzo corrente e controlla se esiste un ordine limite al prezzo corrente che richiede l'aggiunta di liquidità dall'epoca.
5. Gli utenti possono prelevare denaro o aggiungere direttamente liquidità in qualsiasi momento
2.2.3 Spiegazione dettagliata degli esempi
L'hook viene attivato in due fasi della registrazione del contratto. L'hook viene inizializzato dopo l'inizializzazione del Pool e la logica dell'hook viene attivata dopo ogni scambio.
L'utente chiama la funzione place per trasferire la quantità, il prezzo e la direzione di trading in cui l'utente desidera aggiungere liquidità. L'hook aggiungerà prima la liquidità che l'utente desidera aggiungere al pool e la salverà, quindi creerà un limite corrispondente ordine per l'utente.
Questo hook verrà attivato dopo ogni swap e gli ordini limite esistenti all'interno della fascia di prezzo completeranno l'operazione di aggiunta di liquidità in base alla fascia di prezzo corrente.
Gli utenti possono richiamare la funzione kill prima che l'ordine limite venga completato per annullare l'ordine limite e ottenere i benefici da questa liquidità aggiunta.
Gli utenti possono richiamare la funzione di prelievo quando desiderano rimuovere liquidità per estrarre la liquidità desiderata.
In generale, questo hook dell'ordine limite fornisce un modo più conveniente per gli utenti. Gli utenti possono impostare il prezzo quando desiderano aggiungere liquidità. Dopo che l'intervallo di prezzo nel pool ha raggiunto il prezzo, l'hook lo aggiunge automaticamente al pool per l'utente. Viene eseguita l'operazione di aggiunta di liquidità e gli utenti possono annullare e prelevare liquidità in qualsiasi momento.
Oltre a TWAMM e Limit Order, il reinvestimento LP, le modifiche dinamiche delle commissioni e altre funzioni possono essere implementate anche sulla base dell'Hook. Per motivi di spazio, le introdurremo nella successiva analisi:
Reinvestimento LP: gli utenti possono utilizzare gli hook per aggiungere, modificare e rimuovere liquidità. Gli hook possono registrare afterSwap e afterModifyPosition per le chiamate. Poiché gli utenti utilizzano uniformemente gli hook per aggiungere liquidità, gli unici indirizzi che aggiungono liquidità nel poolManager sono gli hook. Gli hook possono controllare l'ora corrente ogni volta che vengono attivati. Dopo un certo periodo di tempo, scelgono di ritirare i premi di liquidità e riceveranno The I token LP vengono nuovamente aggiunti al pool per aggiungere liquidità, ottimizzando così automaticamente i vantaggi per l'utente.
Modifiche dinamiche delle tariffe: gli hook possono registrare interfacce come beforeSwap per modificare le tariffe dinamiche prima dello scambio. Le commissioni di gestione dinamica non possono semplicemente cambiare linearmente in base al tempo, ma possono quantificare la volatilità in base al numero di salti di tick generati da un singolo swap, modificando così dinamicamente le commissioni di gestione e ottenendo una copertura contro i rischi temporanei di LP. Riducendo così l’impatto delle perdite temporanee causate dalle transazioni sui fornitori di liquidità.
Nella logica della funzione relativa agli hook di chiamata del pool, provare a ridurre l'uso delle istruzioni di rollback Poiché il contratto del pool e il contratto degli hook hanno una relazione comune, dopo che si verifica un rollback della transazione negli hook, verrà eseguito il rollback anche della transazione nel pool. back. If La presenza di istruzioni di rollback negli hook che non sono correlate alle normali transazioni nel pool potrebbe impedire agli utenti di utilizzare normalmente le funzioni nel pool.
Evitare di utilizzare la funzione di autodistruzione nell'hook Se la funzione di autodistruzione viene richiamata nell'hook, non solo causerà problemi con la logica nell'hook, ma causerà anche il mancato funzionamento corretto delle funzioni nel pool, causando il danneggiamento delle risorse. nell'intera piscina da perdere e le funzioni da disattivare Procedere normalmente.
Controlla rigorosamente le autorizzazioni
Controllare rigorosamente le autorizzazioni nel contratto hook per evitare ruoli con autorizzazioni eccessive e condurre una gestione multifirma dei ruoli privilegiati per prevenire attacchi a punto singolo. Evitare la situazione in cui i ruoli privilegiati possono modificare a piacimento le variabili di stato del contratto. Errori logici possono causare il rollback dell'intera transazione, influenzando il normale utilizzo del pool. Per verificare il principio del privilegio minimo, dovremmo utilizzare il contratto AccessControl di openzeppelin per controllare l'accesso a permessi più dettagliati, perché questa pratica limita ogni componente del sistema a seguire il principio del privilegio minimo.
Attuare restrizioni anti-rientro
Come codice di estensione esterno del Pool, gli hook dovrebbero prestare attenzione anche ai possibili attacchi di rientro nel contratto. Ad esempio, il rientro potrebbe verificarsi quando si eseguono trasferimenti di token nativi in ordini limite, con conseguente perdita di risorse contrattuali. Controlla e prova ad aggiornare tutti gli stati prima di chiamare contratti esterni o il cosiddetto modello "check-validate-interact". In questo modo, anche se rientri, non ci sarà alcun impatto perché tutto lo stato è stato aggiornato. .
Controllo dell'aggiornamento del contratto
Alcuni sviluppatori potrebbero utilizzare contratti proxy per apportare modifiche e aggiornamenti successivi alla logica dell'hook, ma devono anche essere consapevoli dei possibili problemi con gli aggiornamenti dei contratti. Innanzitutto, anche se nell'hook viene adottata la modalità proxy, è necessario dichiarare nel contratto proxy la fase corrispondente, ad esempio beforeSwap, ecc. In caso contrario il pool non potrà verificare il corretto valore restituito. In secondo luogo, controlla se il contratto di destinazione esiste prima di chiamare delegatecall. Solidity non eseguirà questo controllo per noi. Ignorare il controllo può portare a comportamenti imprevisti e problemi di sicurezza. Considerare attentamente l'ordine di dichiarazione delle variabili, poiché le variabili potrebbero essere impacchettate e archiviate nel file stesso slot Problemi relativi al costo del gas, al layout della memoria, ai risultati delle chiamate dei delegati, ecc.
Chi siamo
La visione di SharkTeam è proteggere in modo completo il mondo Web3. Il team è composto da professionisti esperti della sicurezza e ricercatori senior provenienti da tutto il mondo. Sono esperti nella teoria alla base della blockchain e dei contratti intelligenti e forniscono servizi tra cui audit dei contratti intelligenti, analisi on-chain, risposta alle emergenze e altri servizi. Ha stabilito rapporti di cooperazione a lungo termine con attori chiave in vari campi dell'ecosistema blockchain, come Polkadot, Moonbeam, polygon, OKC, Huobi Global, imToken, ChainIDE, ecc.
