Address Contract Verified
Address
0x686132342Dc6D899c973C48Ea074C2759c02e65e
Balance
0 ETH
Nonce
1
Code Size
10276 bytes
Creator
0x49f8A1C3...E797 at tx 0x40a1fadf...011544
Indexed Transactions
0
Contract Bytecode
10276 bytes
0x60406080815260048036101561001457600080fd5b600091823560e01c9081621d35671461161457816301ffc9a7146115bd57816306fdde03146114f8578163095ea7b3146114ce5781630f1f9cfc1461148a578163116191b614611446578163180f6cc21461141857816318160ddd146113f95781631a98b2e01461129b57816320767b30146111b957816322282f031461118957816323b872dd1461114c57816325c7e35b146110d8578163313ce567146110bc578163380064a8146110495781633950935114610ffa5781634916065814610c2e578163529dca3214610a58578163543746b114610a3b57816359e741d214610a1c578382636d9bef4214610992575081636fad06f51461094e57816370a082311461091757816385f2aef2146108ee5781638ab0510d146108c557816395d89b41146107e4578163997f35eb146107a05781639dc29fac1461075f578163a0ff97f314610696578163a457c2d7146105f0578163a9059cbb146105bf578163b2783acb146104fb578163b7edaaf6146103a1578163b963111414610361578163c8e7698214610263578163dd62ed3e14610215575063facea41e146101ba57600080fd5b60a03660031901126102115780356001600160401b03811161020d5761020a916101e6913691016118e8565b906101ef6118d2565b6101f76118a6565b906102006118bc565b9360643593612011565b80f35b8280fd5b5080fd5b839034610211578060031936011261021157602091610232611890565b8261023b6118d2565b6001600160a01b03928316845260018652922091166000908152908352819020549051908152f35b9050823461035e578060031936011261035e57508051906000906005549160018360011c9060018516948515610354575b60209586841081146103415783885287949392918790821561031f5750506001146102df575b50506102db92916102cc9103856117c9565b51928284938452830190611850565b0390f35b90859250600560005282600020916000925b82841061030757505050820101816102cc6102ba565b8054848a0186015288955087949093019281016102f1565b60ff19168682015292151560051b850190920192508391506102cc90506102ba565b634e487b7160e01b855260228952602485fd5b91607f1691610294565b80fd5b8360c036600319011261035e5761020a610379611763565b6103816118d2565b9061038a6118a6565b906103936118bc565b9160a4359360643592611e85565b82843461035e576003199060c03683011261035e576103be611763565b916103c76118d2565b906103d06118a6565b916084359384151580950361035e5760a435906001600160401b03821161035e57508795936104789361046461ffff97946104116104379536908d016118e8565b9590946104298c519384926064359160208501611af4565b03601f1981018352826117c9565b89519a8b998a9963040a7bb160e41b8b52169089015230602489015260a0604489015260a4880190611850565b9360648701528584030160848601526119ee565b03817f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6756001600160a01b03165afa9081156104f057916020926000926104c0575b5051908152f35b816104e19293503d84116104e9575b6104d981836117c9565b810190611a4a565b5090836104b9565b503d6104cf565b82513d6000823e3d90fd5b91905060a036600319011261020d57803591610515611774565b918461051f6118a6565b91610528611915565b6009549094906001600160a01b0316803b156105bb5787849161056194838551809781958294632770a7eb60e21b845233908401611a0f565b03925af19081156105b2575061059a575b505061058461020a9460085490611a2a565b9061058f8233612312565b608435933390611e85565b6105a390611785565b6105ae578438610572565b8480fd5b513d84823e3d90fd5b8380fd5b8390346102115780600319360112610211576020906105e96105df611890565b602435903361253d565b5160018152f35b82843461035e578260031936011261035e5761060a611890565b91836024359233815260016020522060018060a01b038416600052602052836000205490828210610645576020856105e985850387336123a3565b608490602086519162461bcd60e51b8352820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152fd5b9050608036600319011261020d578135916024356001600160401b0381116105ae576106c590369083016118e8565b9190856106d06118a6565b926106d9611915565b6009549096906001600160a01b0316803b156105bb5788849161071294838551809781958294632770a7eb60e21b845233908401611a0f565b03925af19081156105b25750610747575b505061073561020a9560085490611a2a565b926107408433612312565b3391612011565b61075090611785565b61075b578538610723565b8580fd5b8390346102115736600319011261035e5761020a61077b611890565b602435906001600160a01b0381163314612699575b61079b8233836124a5565b612699565b839034610211578160031936011261021157517f0000000000000000000000002d5d7d31f671f86c782533cc367f14109a0827126001600160a01b03168152602090f35b9050823461035e578060031936011261035e575080519060009083549160018360011c90600185169485156108bb575b6020958684108114610341579086889992858a98999a529182600014610894575050600114610851575b5050506102db92916102cc9103856117c9565b86935060009291925282600020916000925b82841061087c57505050820101816102cc6102db61083e565b8054848a018601528895508794909301928101610863565b60ff19168782015293151560051b860190930193508492506102cc91506102db905061083e565b91607f1691610814565b83903461021157816003193601126102115760095490516001600160a01b039091168152602090f35b83903461021157816003193601126102115760075490516001600160a01b039091168152602090f35b8390346102115760203660031901126102115760209181906001600160a01b0361093f611890565b16815280845220549051908152f35b839034610211578160031936011261021157517f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6756001600160a01b03168152602090f35b9150913461021157602036600319011261021157600954813593906001600160a01b0316803b156105bb578484916109e094838551809781958294632770a7eb60e21b845233908401611a0f565b03925af19081156105b25750610a08575b5061020a610a028360085490611a2a565b33612312565b610a1190611785565b6102115781386109f1565b8390346102115781600319360112610211576020906008549051908152f35b8390346102115736600319011261035e57610a54611890565b5080f35b91905060a036600319011261020d576001600160401b039080358281116105ae57610a869036908301611832565b60249260243593818511610c2a5736602386011215610c2a578484013594828611610c17578560051b916024602080988a5190610ac5838801836117c9565b8152019383010193368511610c135760248301935b858510610be9575050505050506064359061ffff8216809203610be4576084358087526006855260ff8688205416610bd457865260068452848620805460ff191660011790556001600160a01b03927f00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d89491184163303610bc65783604435163003610bb8575091610bb28192610b8585878060008051602061278f83398151915298518301019101611953565b9891941696610b948989612312565b815192818401528252610ba6826117ae565b519384931696836119b8565b0390a380f35b85516309aa97f760e31b8152fd5b85516381316de160e01b8152fd5b855163bed444bb60e01b81528490fd5b600080fd5b8435828111610c0f578991610c048392863691890101611832565b815201940193610ada565b8b80fd5b8980fd5b634e487b7160e01b885260418552602488fd5b8680fd5b9190503461020d576003196080368201126105bb576024926001600160401b039185919085358481116105bb57610c6890369087016118e8565b94909560443582811161075b57610c8290369083016118e8565b989092606435908111610c2a57610c9c90369084016118e8565b93909936610cab90868d6117ec565b95865196602097888092012091600160a01b600190039a8d8d8c5195869485938493635f6970c360e01b85528d8035908601528c8501608090526084850190610cf3926119ee565b90838203016044840152610d0890898b6119ee565b90606483015203918d7f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a5165af1908115610ff0578d91610fc3575b5015610fb35790610d559136916117ec565b80518b92602a929183811480159190610f91575b508015610f5a575b610f4a57600292918391905b838510610e1b5750505050508530911603610e0d57508660609181010312610c2a5760008051602061278f8339815191529382610e0183610df3878b97610dd1610bb298610dca8b61192b565b9a0161192b565b9c01359b1699610de18c8c612312565b845195838794850152858401916119ee565b03601f1981018452836117c9565b5193849316968361199a565b835163063ce8cd60e31b8152fd5b90919293948151861015610f365788868301015160f81c606181101580610f2b575b15610e9f5760ff90811660561901908111610e8b575b602990878203918211610e775760ff1690851b1b8b16179460010193929190610d7d565b5050634e487b7160e01b8f5260118752828ffd5b83601189634e487b7160e01b600052526000fd5b604181101580610f20575b15610ed45760ff9081166036190190811115610e535783601189634e487b7160e01b600052526000fd5b603081101580610f15575b15610f0557602f190160ff811115610e535783601189634e487b7160e01b600052526000fd5b8a51636fa478cf60e11b81528890fd5b506039811115610edf565b506046811115610eaa565b506066811115610e3d565b82603288634e487b7160e01b600052526000fd5b8751636fa478cf60e11b81528590fd5b50815160011015610f805760218201516001600160f81b031916600f60fb1b1415610d71565b634e487b7160e01b8d52603285528cfd5b905015610f8057818701516001600160f81b031916600360fc1b141538610d69565b8651631403112d60e21b81528490fd5b610fe39150873d8911610fe9575b610fdb81836117c9565b8101906119d6565b38610d43565b503d610fd1565b88513d8f823e3d90fd5b8390346102115780600319360112610211576105e96020928261101b611890565b91338152600186522060018060a01b03821660005284526110426024358460002054611e62565b90336123a3565b9190503461020d578160031936011261020d57611064611890565b6007546001600160a01b039290831633036110ae57600954938385166110a15750506001600160a01b031990921691161760095560243560085580f35b5163be8be5cf60e01b8152fd5b835163b665981560e01b8152fd5b8390346102115781600319360112610211576020905160128152f35b505060e0366003190112610211576110ee611763565b6110f66118d2565b6110fe6118a6565b916111076118bc565b60a435916001600160a01b0383168303610be45760c4356001600160401b0381116111485761020a9661113c913691016118e8565b95909460643592611b16565b8780fd5b839034610211576060366003190112610211576020906105e961116d611890565b6111756118d2565b604435916111848333836124a5565b61253d565b8390346102115780600319360112610211576020906111b26111a9611763565b60243590611a60565b9051908152f35b83915060c0366003190112610211578235926111d3611774565b6111db6118a6565b906111e4611915565b906111ed6118bc565b9260a4356001600160401b0381116111485761120c90369087016118e8565b96909560018060a01b036009541690813b15610c13578a83928b92836112469651809781958294632770a7eb60e21b845233908401611a0f565b03925af1908115611292575061127b575b5061126961020a979860085490611a2a565b916112748333612312565b3390611b16565b61020a9761128b61126992611785565b9750611257565b513d8a823e3d90fd5b90503461020d5760031960c0368201126105bb576001600160401b039060243582811161075b576112cf90369086016118e8565b9092604435818111611148576112e890369088016118e8565b606435838111610c13576112ff9036908a016118e8565b6084359485116113f5576020966104646113709561132e6113248e9936908b016118e8565b96909536916117ec565b8a8151910120956113608d519c8d9b8c9b631876eed960e01b8d528035908d015260c060248d015260c48c01916119ee565b91848a84030160448b01526119ee565b60a48035908301520381877f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a56001600160a01b03165af19081156113eb5784916113cc575b50156113bf578280f35b51631403112d60e21b8152fd5b6113e5915060203d602011610fe957610fdb81836117c9565b386113b5565b82513d86823e3d90fd5b8a80fd5b8390346102115781600319360112610211576020906002549051908152f35b9190503461020d57602036600319011261020d578160209360ff923581526006855220541690519015158152f35b839034610211578160031936011261021157517f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a56001600160a01b03168152602090f35b839034610211578160031936011261021157517f00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d8949116001600160a01b03168152602090f35b8390346102115780600319360112610211576020906105e96114ee611890565b60243590336123a3565b9050823461035e578060031936011261035e57815191816003549260018460011c91600186169586156115b3575b60209687851081146115a0578899509688969785829a529182600014610894575050600114611562575050506102db92916102cc9103856117c9565b9190869350600383528383205b82841061158857505050820101816102cc6102db61083e565b8054848a01860152889550879490930192810161156f565b634e487b7160e01b835260228a52602483fd5b92607f1692611526565b9190503461020d57602036600319011261020d57359063ffffffff60e01b821680920361020d576020925063543746b160e01b8214918215611603575b50519015158152f35b6301ffc9a760e01b149150386115fa565b90503461020d57608036600319011261020d5761162f611763565b916001600160401b039060243582811161075b576116509036908301611832565b916044358181160361075b5760643590811161075b576116739036908301611832565b6001600160a01b0392909190337f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6758516036117545780516020909101516001600160601b03199182821691906014811061173f575b5050905060601c300361173157509080610bb26116fd8460208060008051602061278f83398151915297518301019101611953565b979193169561170c8888612312565b61ffff81519216602083015260208252611725826117ae565b5193849316968361197c565b83516347cec4bb60e11b8152fd5b8391925060140360031b1b16168038806116c8565b50835163a667bffb60e01b8152fd5b6004359061ffff82168203610be457565b6024359061ffff82168203610be457565b6001600160401b03811161179857604052565b634e487b7160e01b600052604160045260246000fd5b604081019081106001600160401b0382111761179857604052565b601f909101601f19168101906001600160401b0382119082101761179857604052565b9192916001600160401b0382116117985760405191611815601f8201601f1916602001846117c9565b829481845281830111610be4578281602093846000960137010152565b9080601f83011215610be45781602061184d933591016117ec565b90565b919082519283825260005b84811061187c575050826000602080949584010152601f8019910116010190565b60208183018101518483018201520161185b565b600435906001600160a01b0382168203610be457565b604435906001600160a01b0382168203610be457565b608435906001600160a01b0382168203610be457565b602435906001600160a01b0382168203610be457565b9181601f84011215610be4578235916001600160401b038311610be45760208381860195010111610be457565b606435906001600160a01b0382168203610be457565b35906001600160a01b0382168203610be457565b51906001600160a01b0382168203610be457565b90816060910312610be4576119678161193f565b9160406119766020840161193f565b92015190565b60609061184d93928152600060208201528160408201520190611850565b60609061184d93928152600260208201528160408201520190611850565b60609061184d93928152600160208201528160408201520190611850565b90816020910312610be457518015158103610be45790565b908060209392818452848401376000828201840152601f01601f1916010190565b6001600160a01b039091168152602081019190915260400190565b8115611a34570490565b634e487b7160e01b600052601260045260246000fd5b9190826040910312610be4576020825192015190565b6040805163c23ee3c360e01b815261ffff909216600483015260006024830152604482019290925290816064817f00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d8949116001600160a01b03165afa908115611ae857600091611acb575090565b611ae4915060403d6040116104e9576104d981836117c9565b5090565b6040513d6000823e3d90fd5b6001600160a01b03918216815291166020820152604081019190915260600190565b93969194929390926001600160a01b03908116929183611d945760408381611b848a611b4e8a6104298d865194859360208501611af4565b611b9d8d8451958694859463040a7bb160e41b865261ffff8b16600487015230602487015260a0604487015260a4860190611850565b60006064860152848103600319016084860152916119ee565b0381877f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675165afa9081156104f057600091611d76575b503410611d6757505b81851697883303611d57575b611bf28787612699565b828816998a15611d4557837f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675169460409788519a60208c3060601b918291015260348d015260288c5260608c01918c831060018060401b0384111761179857611c678c611c79938f93868f5260808501611af4565b03607f1981018352605f1901826117c9565b863b15610be4578851978896879662c5803160e81b885261ffff169c8d60048901526024880160c0905260c48801611cb091611850565b9260031993848982030160448a0152611cc891611850565b9416606487015260848601528483030160a4850152611ce6926119ee565b0381345a94600095f180156104f05791611d31916000805160206127af833981519152959493611d36575b50805193602085015260208452611d27846117ae565b519283928361197c565b0390a3565b611d3f90611785565b38611d11565b604051638aa3a72f60e01b8152600490fd5b611d628733886124a5565b611be8565b5162976f7560e21b8152600490fd5b611d8d9150823d84116104e9576104d981836117c9565b5038611bd3565b60408381611de88a611db28a6104298d865194859360208501611af4565b611e018d8451958694859463040a7bb160e41b865261ffff8b16600487015230602487015260a0604487015260a4860190611850565b60016064860152848103600319016084860152916119ee565b0381877f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675165afa9081156104f057600091611e44575b503410611d675750611bdc565b611e5b9150823d84116104e9576104d981836117c9565b5038611e37565b91908201809211611e6f57565b634e487b7160e01b600052601160045260246000fd5b949392919093611e958187611a60565b3410611fff576001600160a01b038581169533879003611fef575b611eba8582612699565b818416978815611d45578261ffff611f269260405199611ef38b611ee58c60209c8d9a8b8501611af4565b03601f1981018d528c6117c9565b604051968795869485946312d729bd60e21b8652169c8d600486015230602486015260e0604486015260e4850190611850565b916000998a606486015260848501528c60a48501521660c4830152039134907f00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911165af18015611fe457611faa575b5050906000805160206127af833981519152929160405192818401528252611f9b826117ae565b611d31604051928392836119b8565b8281813d8311611fdd575b611fbf81836117c9565b8101031261021157516001600160401b0381160361035e5780611f74565b503d611fb5565b6040513d84823e3d90fd5b611ffa8533836124a5565b611eb0565b6040516306807deb60e41b8152600490fd5b929493919360405161202c81610429868a8a60208501611af4565b60405160006005549060018260011c92600181168015612308575b6020851081146122f4578486528593929181156122d25750600114612273575b50612074925003826117c9565b60009234612186575b5060018060a01b03809861209b87838b169a338c0361079057612699565b16978815611d45577f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a51691823b156105bb5761211592878587612124829661210296604051998a9889978896631c92115f60e01b88526060600489015260648801916119ee565b6003199384878303016024880152611850565b91848303016044850152611850565b03925af18015611fe457612172575b5050906121636000805160206127af8339815191529392610df360405194859260208085015260408401916119ee565b611d316040519283928361199a565b61217c8291611785565b61035e5780612133565b7f0000000000000000000000002d5d7d31f671f86c782533cc367f14109a0827126001600160a01b03163b156105bb5783604051808093630c93e3bb60e01b825230600483015260a0602483015261220d6121e68c8b60a48601916119ee565b6121fd600319918286820301604487015289611850565b9084820301606485015288611850565b6001600160a01b0391821660848401529190910390829034907f0000000000000000000000002d5d7d31f671f86c782533cc367f14109a082712165af18015612268571561207d5761226190939193611785565b913861207d565b6040513d86823e3d90fd5b6005600090815291507f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db05b8483106122b75750612074935050810160200138612067565b8193509081602092548385890101520191019091849261229e565b90506020925061207494915060ff191682840152151560051b82010138612067565b634e487b7160e01b84526022600452602484fd5b93607f1693612047565b6001600160a01b031690811561235e576000805160206127cf833981519152602082612342600094600254611e62565b60025584845283825260408420818154019055604051908152a3565b60405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606490fd5b6001600160a01b0390811691821561245457169182156124045760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925918360005260018252604060002085600052825280604060002055604051908152a3565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608490fd5b60405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b9060018060a01b03808316600052600160205260406000209082166000526020526040600020549260001984036124dd575b50505050565b8084106124f8576124ef9303916123a3565b388080806124d7565b60405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606490fd5b6001600160a01b0390811691821561264657169182156125f5576000828152806020526040812054918083106125a157604082826000805160206127cf833981519152958760209652828652038282205586815220818154019055604051908152a3565b60405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608490fd5b6001600160a01b0316801561273f576000918183528260205260408320548181106126ef57816000805160206127cf833981519152926020928587528684520360408620558060025403600255604051908152a3565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608490fdfe51fa6b13f6daaeb242e226abef2a9ff882bc8f2559829aa56db5baddc7a494b4910681e1ddfdfd81641e12c78e640eb5928c78b55a791eeec551d2c3bd1581e2ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212200fa538969eba766f2175029d21d37cc43c63dd3316e07bb5f7ac6977262e0f7264736f6c63430008190033
Verified Source Code Full Match
Compiler: v0.8.25+commit.b61c2a91
EVM: paris
Optimization: Yes (1 runs)
vXNF.sol 309 lines
// SPDX-License-Identifier: Unlicensed
pragma solidity 0.8.25;
import {MerkleProof} from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import {ERC165, IERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import {IBurnRedeemable} from "./interfaces/IBurnRedeemable.sol";
import {IBurnableToken} from "./interfaces/IBurnableToken.sol";
import {ICore} from "./interfaces/ICore.sol";
import {IvXNF} from "./interfaces/IvXNF.sol";
import {IALX} from "./interfaces/IALX.sol";
import {Bridge} from "./base/Bridge.sol";
/*
* @title vXNF Contract
*
* @notice Implements the vXNF token, an ERC20 token with advanced bridging and burning capabilities.
*
* @dev This contract extends the Bridge contract and implements IvXNF and ERC165 interfaces.
* It provides functionalities for burning XNF tokens, minting vXNF tokens, and bridging
* tokens across different EVM chains using LayerZero, Axelar, and Wormhole protocols.
*
* Co-Founders:
* - Simran Dhillon: [email protected]
* - Hardev Dhillon: [email protected]
* - Dayana Plaz: [email protected]
*
* Official Links:
* - Twitter: https://twitter.com/xenify_io
* - Telegram: https://t.me/xenify_io
* - Website: https://xenify.io
*
* Disclaimer:
* This contract aligns with the principles of the Fair Crypto Foundation, promoting self-custody, transparency, consensus-based
* trust, and permissionless value exchange. There are no administrative access keys, underscoring our commitment to decentralization.
* Engaging with this contract involves technical and legal risks. Users must conduct their own due diligence and ensure compliance
* with local laws and regulations. The software is provided "AS-IS," without warranties, and the co-founders and developers disclaim
* all liability for any vulnerabilities, exploits, errors, or breaches that may occur. By using this contract, users accept all associated
* risks and this disclaimer. The co-founders, developers, or related parties will not bear liability for any consequences of non-compliance.
*
* Redistribution and Use:
* Redistribution, modification, or repurposing of this contract, in whole or in part, is strictly prohibited without express written
* approval from all co-founders. Approval requests must be sent to the official email addresses of the co-founders, ensuring responses
* are received directly from these addresses. Proposals for redistribution, modification, or repurposing must include a detailed explanation
* of the intended changes or uses and the reasons behind them. The co-founders reserve the right to request additional information or
* clarification as necessary. Approval is at the sole discretion of the co-founders and may be subject to conditions to uphold the
* project’s integrity and the values of the Fair Crypto Foundation. Failure to obtain express written approval prior to any redistribution,
* modification, or repurposing will result in a breach of these terms and immediate legal action.
*
* Copyright and License:
* Copyright © 2024 Xenify (Simran Dhillon, Hardev Dhillon, Dayana Plaz). All rights reserved.
* This software is provided 'as is' and may be used by the recipient. No permission is granted for redistribution,
* modification, or repurposing of this contract. Any use beyond the scope defined herein may be subject to legal action.
*/
contract vXNF is
Bridge,
IvXNF,
ERC165
{
/// ------------------------------------ VARIABLES ------------------------------------- \\\
/**
* @notice Immutable team address used for setting XNF address.
* @dev This address has the exclusive right to set the XNF token address and ratio.
*/
address public team;
/**
* @notice Ratio used for token conversions between XNF and vXNF.
* @dev This ratio determines how many XNF tokens are equivalent to one vXNF token.
*/
uint256 public RATIO;
/// ------------------------------------ INTERFACES ------------------------------------- \\\
/**
* @notice Interface to interact with the XNF token contract.
* @dev This interface allows for burning XNF tokens and other token-specific operations.
*/
IBurnableToken public XNF;
/// ------------------------------------ CONSTRUCTOR ------------------------------------ \\\
/**
* @notice Constructs the vXNF token and initialises its dependencies.
* @dev Sets up the vXNF token with references to other contracts and initialises the token supply.
* @param _ratio The initial ratio between vXNF and XNF used for minting and burning.
* @param _XNF The address of the XNF token contract.
* @param _gateway Address of the Axelar gateway contract.
* @param _gasService Address of the Axelar gas service contract.
* @param _endpoint Address of the LayerZero endpoint contract.
* @param _wormholeRelayer Address of the Wormhole relayer contract.
* @param _teamAddress Address of the team's wallet.
* @param users Array of addresses to receive initial token allocation.
* @param amounts Array of token amounts corresponding to each address in 'users'.
*/
constructor(
uint256 _ratio,
address _XNF,
address _gateway,
address _gasService,
address _endpoint,
address _wormholeRelayer,
address _teamAddress,
address[] memory users,
uint256[] memory amounts
) payable
Bridge(
"vXNF",
"vXNF",
_gateway,
_gasService,
_endpoint,
_wormholeRelayer
)
{
XNF = IBurnableToken(_XNF);
RATIO = _ratio;
team = _teamAddress;
for (uint256 i = 0; i < users.length; i++) {
_mint(users[i], amounts[i]);
}
}
/// --------------------------------- EXTERNAL FUNCTIONS -------------------------------- \\\
/**
* @notice A hook triggered post token burning.
* @dev This function is called after tokens are burned. It currently has no implementation
* but can be overridden for additional post-burn logic if needed in the future.
* @param user The address of the user whose tokens were burned.
* @param amount The amount of tokens that were burned.
*/
function onTokenBurned(
address user,
uint256 amount
) external {}
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Burns a specified quantity of XNF tokens and mints an equivalent quantity of vXNF tokens.
* @dev This function burns XNF tokens from the sender and mints vXNF tokens according to the defined RATIO.
* @param _amount The volume of XNF tokens to burn.
*/
function burnXNF(uint256 _amount) external override {
XNF.burn(msg.sender, _amount);
uint256 amt;
unchecked {
amt = _amount / RATIO;
}
_mint(msg.sender, amt);
}
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Burns XNF tokens and bridges the equivalent vXNF tokens via the LayerZero network.
* @dev Burns XNF tokens, mints vXNF, and initiates a bridge operation using LayerZero.
* @param _amount The amount of XNF tokens to burn.
* @param _dstChainId The Chain ID of the destination chain on the LayerZero network.
* @param _to The recipient address on the destination chain.
* @param _feeRefundAddress Address to refund any excess fees.
* @param _zroPaymentAddress Address of the ZRO token holder who would pay for the transaction.
* @param _adapterParams Parameters for custom functionality.
*/
function burnAndBridgeViaLayerZero(
uint256 _amount,
uint16 _dstChainId,
address _to,
address payable _feeRefundAddress,
address _zroPaymentAddress,
bytes calldata _adapterParams
) external payable override {
XNF.burn(msg.sender, _amount);
uint256 amt;
unchecked {
amt = _amount / RATIO;
}
_mint(msg.sender, amt);
bridgeViaLayerZero(
_dstChainId,
msg.sender,
_to,
amt,
_feeRefundAddress,
_zroPaymentAddress,
_adapterParams
);
}
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Burns XNF tokens and bridges the equivalent vXNF tokens via the Axelar network.
* @dev Burns XNF tokens, mints vXNF, and initiates a bridge operation using Axelar.
* @param _amount The amount of XNF tokens to burn.
* @param _dstChainId The target chain where tokens should be bridged to on the Axelar network.
* @param _to The recipient address on the destination chain.
* @param _feeRefundAddress Address to refund any excess fees.
*/
function burnAndBridgeViaAxelar(
uint256 _amount,
string calldata _dstChainId,
address _to,
address payable _feeRefundAddress
) external payable override {
XNF.burn(msg.sender, _amount);
uint256 amt;
unchecked {
amt = _amount / RATIO;
}
_mint(msg.sender, amt);
bridgeViaAxelar(
_dstChainId,
msg.sender,
_to,
amt,
_feeRefundAddress
);
}
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Burns XNF tokens and bridges the equivalent vXNF tokens via the Wormhole network.
* @dev Burns XNF tokens, mints vXNF, and initiates a bridge operation using Wormhole.
* @param _amount The amount of XNF tokens to burn.
* @param _targetChain The ID of the target chain on the Wormhole network.
* @param _to The recipient address on the destination chain.
* @param _feeRefundAddress Address to refund any excess fees.
* @param _gasLimit The gas limit for the transaction on the destination chain.
*/
function burnAndBridgeViaWormhole(
uint256 _amount,
uint16 _targetChain,
address _to,
address payable _feeRefundAddress,
uint256 _gasLimit
) external payable override {
XNF.burn(msg.sender, _amount);
uint256 amt;
unchecked {
amt = _amount / RATIO;
}
_mint(msg.sender, amt);
bridgeViaWormhole(
_targetChain,
msg.sender,
_to,
amt,
_feeRefundAddress,
_gasLimit
);
}
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Burns a specific amount of vXNF tokens from a user's address.
* @dev Allows an external entity to burn tokens from a user's address, given proper allowance.
* @param _user The address from which the vXNF tokens will be burned.
* @param _amount The amount of vXNF tokens to burn.
*/
function burn(address _user, uint256 _amount) external override {
if (_user != msg.sender)
_spendAllowance(_user, msg.sender, _amount);
_burn(_user, _amount);
}
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Sets the XNF contract address and the conversion ratio.
* @dev This function can only be called once by the team address to set the XNF contract and ratio.
* @param _XNF The XNF contract address.
* @param _ratio The ratio between vXNF and XNF used for minting and burning.
*/
function setXNFAndRatio(address _XNF, uint256 _ratio) external override {
if (msg.sender != team) {
revert OnlyTeamAllowed();
}
if (address(XNF) != address(0)) {
revert XNFIsAlreadySet();
}
XNF = IBurnableToken(_XNF);
RATIO = _ratio;
}
/// ---------------------------------- PUBLIC FUNCTION ---------------------------------- \\\
/**
* @notice Checks if a given interface ID is supported by the contract.
* @dev Implements the IERC165 standard for interface detection.
* @param _interfaceId The ID of the interface in question.
* @return bool `true` if the interface is supported, otherwise `false`.
*/
function supportsInterface(bytes4 _interfaceId)
public
view
override
returns (bool)
{
return _interfaceId == type(IBurnRedeemable).interfaceId || super.supportsInterface(_interfaceId);
}
/// ------------------------------------------------------------------------------------- \\\
}
Bridge.sol 532 lines
// SPDX-License-Identifier: Unlicensed
pragma solidity 0.8.25;
import {StringToAddress, AddressToString} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/AddressString.sol";
import {IAxelarGasService} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol";
import {AxelarExecutable} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarExecutable.sol";
import {ILayerZeroEndpoint} from "@layerzerolabs/lz-evm-sdk-v1-0.7/contracts/interfaces/ILayerZeroEndpoint.sol";
import {IWormholeRelayer} from "../interfaces/IWormholeRelayer.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {IBridgeToken} from "../interfaces/IBridgeToken.sol";
/*
* @title Bridge Contract
*
* @notice This contract facilitates cross-chain token bridging, utilising LayerZero, Axelar, and Wormhole protocols for interoperable token transfers.
*
* Co-Founders:
* - Simran Dhillon: [email protected]
* - Hardev Dhillon: [email protected]
* - Dayana Plaz: [email protected]
*
* Official Links:
* - Twitter: https://twitter.com/alixa_io
* - Telegram: https://t.me/alixa_io
* - Website: https://alixa.io
*
* Disclaimer:
* This contract aligns with the principles of the Fair Crypto Foundation, promoting self-custody, transparency, consensus-based
* trust, and permissionless value exchange. There are no administrative access keys, underscoring our commitment to decentralisation.
* Engaging with this contract involves technical and legal risks. Users must conduct their own due diligence and ensure compliance
* with local laws and regulations. The software is provided "AS-IS," without warranties, and the co-founders and developers disclaim
* all liability for any vulnerabilities, exploits, errors, or breaches that may occur. By using this contract, users accept all associated
* risks and this disclaimer. The co-founders, developers, or related parties will not bear liability for any consequences of non-compliance.
*
* Redistribution and Use:
* Redistribution, modification, or repurposing of this contract, in whole or in part, is strictly prohibited without express written
* approval from all co-founders. Approval requests must be sent to the official email addresses of the co-founders, ensuring responses
* are received directly from these addresses. Proposals for redistribution, modification, or repurposing must include a detailed explanation
* of the intended changes or uses and the reasons behind them. The co-founders reserve the right to request additional information or
* clarification as necessary. Approval is at the sole discretion of the co-founders and may be subject to conditions to uphold the
* project’s integrity and the values of the Fair Crypto Foundation. Failure to obtain express written approval prior to any redistribution,
* modification, or repurposing will result in a breach of these terms and immediate legal action.
*
* Copyright and License:
* Copyright © 2024 Alixa (Simran Dhillon, Hardev Dhillon, Dayana Plaz). All rights reserved.
* This software is provided 'as is' and may be used by the recipient. No permission is granted for redistribution,
* modification, or repurposing of this contract. Any use beyond the scope defined herein may be subject to legal action.
*/
abstract contract Bridge is
AxelarExecutable,
IBridgeToken,
ERC20
{
/// ------------------------------------- LIBRARYS ------------------------------------- \\\
/**
* @notice Utilise StringToAddress for converting string to address format.
* @dev This library provides functions to convert strings to addresses.
*/
using StringToAddress for string;
/**
* @notice Utilise AddressToString for converting address to string format.
* @dev This library provides functions to convert addresses to strings.
*/
using AddressToString for address;
/// ------------------------------------ VARIABLES ------------------------------------- \\\
/**
* @notice Address of this token in a string format.
* @dev This is used for identifying this contract's address in string format across various bridging protocols.
*/
string public addressThis;
/**
* @notice Interface to interact with LayerZero endpoint for bridging operations.
* @dev This endpoint is used to interact with LayerZero for cross-chain token transfers.
*/
ILayerZeroEndpoint public immutable ENDPOINT;
/**
* @notice Interface to interact with Axelar gas service for estimating transaction fees.
* @dev This gas service is used to estimate and pay for the gas fees required for Axelar's cross-chain operations.
*/
IAxelarGasService public immutable GAS_SERVICE;
/**
* @notice Interface to interact with Wormhole relayer for bridging operations.
* @dev This relayer is used to facilitate cross-chain transfers using the Wormhole protocol.
*/
IWormholeRelayer public immutable WORMHOLE_RELAYER;
/// ------------------------------------- MAPPING --------------------------------------- \\\
/**
* @notice Mapping to prevent replay attacks by storing processed delivery hashes.
* @dev This mapping keeps track of delivery hashes that have already been processed to prevent replay attacks.
*/
mapping (bytes32 => bool) public seenDeliveryVaaHashes;
/// ------------------------------------- MODIFIER -------------------------------------- \\\
/**
* @notice Ensures that a Wormhole message is processed only once to prevent replay attacks.
* @dev This modifier checks if the provided `_deliveryHash` has already been seen. If it has, the transaction is reverted
* to prevent duplicate processing of the same message. If the `_deliveryHash` is new, it marks it as seen to ensure
* the message can't be processed again, thereby securing the contract against replay attacks.
* @param _deliveryHash Unique hash representing the delivery message from the Wormhole relayer, used to track message processing.
*/
modifier replayProtect(bytes32 _deliveryHash) {
if (seenDeliveryVaaHashes[_deliveryHash]) {
revert WormholeMessageAlreadyProcessed();
}
seenDeliveryVaaHashes[_deliveryHash] = true;
_;
}
/// ------------------------------------ CONSTRUCTOR ------------------------------------ \\\
/**
* @notice Initialises a new Bridge contract instance.
* @dev Sets up the essential external contracts and services necessary for bridge operations,
* including LayerZero endpoint, Axelar gas service, and Wormhole relayer.
* @param _name The name of the bridge token.
* @param _symbol The symbol of the bridge token.
* @param _gateway The address of the Axelar gateway contract.
* @param _gasService The address of the Axelar gas service contract.
* @param _endpoint The address of the LayerZero endpoint contract.
* @param _wormholeRelayer The address of the Wormhole relayer contract.
*/
constructor(
string memory _name,
string memory _symbol,
address _gateway,
address _gasService,
address _endpoint,
address _wormholeRelayer
) ERC20(_name, _symbol) AxelarExecutable(_gateway) {
GAS_SERVICE = IAxelarGasService(_gasService);
ENDPOINT = ILayerZeroEndpoint(_endpoint);
WORMHOLE_RELAYER = IWormholeRelayer(_wormholeRelayer);
addressThis = address(this).toString();
}
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Handles the receipt of ALX tokens sent via the LayerZero bridge.
* @dev Called by the LayerZero endpoint to mint ALX tokens for the recipient after a successful cross-chain transfer.
* Validates the caller to ensure it's the LayerZero endpoint and checks the source address matches the expected format.
* Decodes the payload to mint the correct amount of ALX tokens to the rightful recipient.
* @param _srcChainId The source chain's identifier in the LayerZero network from which the tokens are bridged.
* @param _srcAddress Encoded source address from which the tokens were sent, expected to match this contract's address.
* @param _payload Encoded data comprising the sender's and recipient's addresses and the amount of ALX tokens to be minted.
*/
function lzReceive(
uint16 _srcChainId,
bytes memory _srcAddress,
uint64,
bytes memory _payload
)
external
override
{
if (address(ENDPOINT) != msg.sender) {
revert NotVerifiedCaller();
}
if (address(this) != address(uint160(bytes20(_srcAddress)))) {
revert InvalidLayerZeroSourceAddress();
}
(address _from, address _to, uint256 _amount) = abi.decode(
_payload,
(address, address, uint256)
);
_mint(_to, _amount);
emit BridgeReceive(
_to,
_amount,
BridgeId.LayerZero,
abi.encode(_srcChainId),
_from
);
}
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Handles incoming token transfers via the Wormhole bridge.
* @dev This function is designed to be invoked by the Wormhole relayer upon the successful bridging of tokens from another chain.
* It extracts the destination address and the amount from the encoded payload and mints the tokens to the recipient's address.
* Ensures that the function is only callable by the Wormhole relayer and verifies the source address for security purposes.
* @param _payload Encoded information including the recipient's address and the amount of tokens to mint.
* @param _sourceAddress The originating address from the source chain, encoded in bytes32.
* @param _srcChainId Identifier of the source chain from where the bridge transaction originates.
* @param _deliveryHash Unique hash used for replay protection and verification of the relay call's authenticity.
*/
function receiveWormholeMessages(
bytes memory _payload,
bytes[] memory,
bytes32 _sourceAddress,
uint16 _srcChainId,
bytes32 _deliveryHash
)
external
payable
override
replayProtect(_deliveryHash)
{
if (msg.sender != address(WORMHOLE_RELAYER)) {
revert OnlyRelayerAllowed();
}
if (address(this) != address(uint160(uint256(_sourceAddress)))) {
revert InvalidWormholeSourceAddress();
}
(address _from, address _to, uint256 _amount) = abi.decode(
_payload,
(address, address, uint256)
);
_mint(_to, _amount);
emit BridgeReceive(
_to,
_amount,
BridgeId.Wormhole,
abi.encode(_srcChainId),
_from
);
}
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Bridges tokens to a specified chain using the LayerZero protocol.
* @dev Constructs the necessary payload and initiates a token bridge operation via the LayerZero endpoint.
* The function checks if sufficient Ether is provided for the gas fee and then proceeds to burn the tokens from the sender's address.
* @param _dstChainId The ID of the destination chain within the LayerZero network.
* @param _from The address initiating the token bridge on the source chain.
* @param _to The address on the destination chain to receive the tokens.
* @param _amount The number of tokens to bridge.
* @param _feeRefundAddress The address to receive refunds for any excess fee paid.
* @param _zroPaymentAddress Address holding ZRO tokens to cover fees, if applicable.
* @param _adapterParams Parameters for the LayerZero adapter, providing additional bridging configurations.
*/
function bridgeViaLayerZero(
uint16 _dstChainId,
address _from,
address _to,
uint256 _amount,
address payable _feeRefundAddress,
address _zroPaymentAddress,
bytes calldata _adapterParams
)
public
payable
override
{
if (_zroPaymentAddress == address(0)) {
if (msg.value < estimateGasForLayerZero(
_dstChainId,
_from,
_to,
_amount,
false,
_adapterParams
)
)
{
revert InsufficientFee();
}
}
else {
if (msg.value < estimateGasForLayerZero(
_dstChainId,
_from,
_to,
_amount,
true,
_adapterParams
)
)
{
revert InsufficientFee();
}
}
if (msg.sender != _from)
_spendAllowance(
_from,
msg.sender,
_amount
);
_burn(_from, _amount);
if (_to == address(0)) {
revert InvalidToAddress();
}
ENDPOINT.send{value: msg.value} (
_dstChainId,
abi.encodePacked(address(this),address(this)),
abi.encode(
_from,
_to,
_amount
),
_feeRefundAddress,
_zroPaymentAddress,
_adapterParams
);
emit BridgeTransfer(
_from,
_amount,
BridgeId.LayerZero,
abi.encode(_dstChainId),
_to
);
}
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Bridges tokens to a specified chain using the Axelar network.
* @dev Encodes the transaction details and invokes the Axelar gateway for token bridging.
* Ensures the sender has enough tokens and the necessary allowance, then burns the bridged tokens.
* If Ether is sent, it covers the native gas fee for the Axelar contract call.
* @param _destinationChain The identifier of the destination chain within the Axelar network.
* @param _from The address sending the tokens on the source chain.
* @param _to The intended recipient address on the destination chain.
* @param _amount The number of tokens to be bridged.
* @param _feeRefundAddress The address to which any excess Ether should be refunded.
*/
function bridgeViaAxelar(
string calldata _destinationChain,
address _from,
address _to,
uint256 _amount,
address payable _feeRefundAddress
)
public
payable
override
{
bytes memory payload = abi.encode(_from, _to, _amount);
string memory _ALXAddress = addressThis;
if (msg.value != 0) {
GAS_SERVICE.payNativeGasForContractCall{value: msg.value} (
address(this),
_destinationChain,
_ALXAddress,
payload,
_feeRefundAddress
);
}
if (_from != msg.sender)
_spendAllowance(
_from,
msg.sender,
_amount
);
_burn(_from, _amount);
if (_to == address(0)) {
revert InvalidToAddress();
}
gateway.callContract(
_destinationChain,
_ALXAddress,
payload
);
emit BridgeTransfer(
_from,
_amount,
BridgeId.Axelar,
abi.encode(_destinationChain),
_to
);
}
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Bridges tokens to a specified chain using the Wormhole network.
* @dev This function handles the bridging of tokens by first estimating the required gas fee for Wormhole,
* checking if the provided Ether covers the cost, and then initiating the bridge process via the Wormhole relayer.
* It ensures the sender has the necessary token allowance and burns the tokens to be bridged from the sender's address.
* @param _targetChain The identifier of the destination chain within the Wormhole network.
* @param _from The address initiating the token bridge on the source chain.
* @param _to The intended recipient address on the target chain.
* @param _amount The quantity of tokens to be bridged.
* @param _feeRefundAddress The address to which any excess fees should be refunded.
* @param _gasLimit The gas limit for processing the transaction on the destination chain.
*/
function bridgeViaWormhole(
uint16 _targetChain,
address _from,
address _to,
uint256 _amount,
address payable _feeRefundAddress,
uint256 _gasLimit
)
public
payable
override
{
uint256 cost = estimateGasForWormhole(_targetChain, _gasLimit);
if (msg.value < cost) {
revert InsufficientFeeForWormhole();
}
if (msg.sender != _from)
_spendAllowance(
_from,
msg.sender,
_amount
);
_burn(_from, _amount);
if (_to == address(0)) {
revert InvalidToAddress();
}
WORMHOLE_RELAYER.sendPayloadToEvm{value: msg.value} (
_targetChain,
address(this),
abi.encode(_from, _to, _amount),
0,
_gasLimit,
_targetChain,
_feeRefundAddress
);
emit BridgeTransfer(
_from,
_amount,
BridgeId.Wormhole,
abi.encode(_targetChain),
_to
);
}
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Estimates the bridging fee on LayerZero for token transfer.
* @dev Invokes the `estimateFees` function from LayerZero's endpoint contract to calculate the bridging cost.
* @param _dstChainId The destination chain ID on LayerZero where the tokens will be bridged.
* @param _from The address sending tokens on the source chain.
* @param _to The address receiving tokens on the destination chain.
* @param _amount The amount of tokens being bridged.
* @param _payInZRO Indicates if the fee will be paid in ZRO token. If false, the fee is paid in the native chain token.
* @param _adapterParam Adapter-specific parameters that may affect fee calculation.
* @return nativeFee_ The estimated fee for the bridging operation in the native chain token.
*/
function estimateGasForLayerZero(
uint16 _dstChainId,
address _from,
address _to,
uint256 _amount,
bool _payInZRO,
bytes calldata _adapterParam
)
public
override
view
returns (uint256 nativeFee_)
{
(nativeFee_, ) = ENDPOINT.estimateFees(
_dstChainId,
address(this),
abi.encode(_from, _to, _amount),
_payInZRO,
_adapterParam
);
}
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Estimates the bridging fee using the Wormhole network for a specific transaction.
* @dev Calls the `quoteEVMDeliveryPrice` function on the Wormhole relayer contract to determine the fee based on the target chain and gas limit.
* @param _targetChain The ID of the target chain within the Wormhole network where the assets or data will be sent.
* @param _gasLimit The gas limit specified for the transaction on the destination chain, influencing the cost estimation.
* @return cost_ The estimated cost for using Wormhole to bridge the transaction, denoted in the native token of the source chain.
*/
function estimateGasForWormhole(
uint16 _targetChain,
uint256 _gasLimit
)
public
override
view
returns (uint256 cost_)
{
(cost_, ) = WORMHOLE_RELAYER.quoteEVMDeliveryPrice(
_targetChain,
0,
_gasLimit
);
}
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Processes the minting of tokens based on a cross-chain transaction.
* @dev Decodes the provided payload to extract minting details. It validates the source address and mints tokens to the specified recipient.
* This function is internal and is typically called as part of the cross-chain communication logic, ensuring that the token minting
* aligns with the protocol's cross-chain transaction rules.
* @param _sourceChain Identifies the blockchain from which the cross-chain request originated.
* @param _sourceAddress The address on the source chain that initiated the mint request. Must match this contract's address.
* @param _payload Encoded data containing the details of the mint operation, including the recipient's address and the amount to mint.
*/
function _execute(
string calldata _sourceChain,
string calldata _sourceAddress,
bytes calldata _payload
)
internal
override
{
if (_sourceAddress.toAddress() != address(this)) {
revert InvalidSourceAddress();
}
(address _from, address _to, uint256 _amount) = abi.decode(
_payload,
(address, address, uint256)
);
_mint(_to, _amount);
emit BridgeReceive(
_to,
_amount,
BridgeId.Axelar,
abi.encode(_sourceChain),
_from
);
}
/// ------------------------------------------------------------------------------------- \\\
}
IALX.sol 211 lines
// SPDX-License-Identifier: Unlicensed
pragma solidity 0.8.25;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IBurnableToken} from "./IBurnableToken.sol";
import {IBridgeToken} from "./IBridgeToken.sol";
/*
* @title IALX Interface
*
* @notice Interface for the ALX token, incorporating ERC20, burnable, and bridgeable functionalities.
*
* Co-Founders:
* - Simran Dhillon: [email protected]
* - Hardev Dhillon: [email protected]
* - Dayana Plaz: [email protected]
*
* Official Links:
* - Twitter: https://twitter.com/alixa_io
* - Telegram: https://t.me/alixa_io
* - Website: https://alixa.io
*
* Disclaimer:
* This interface aligns with the principles of the Fair Crypto Foundation, promoting self-custody, transparency, consensus-based
* trust, and permissionless value exchange. There are no administrative access keys, underscoring our commitment to decentralisation.
* Engaging with this interface involves technical and legal risks. Users must conduct their own due diligence and ensure compliance
* with local laws and regulations. The software is provided "AS-IS," without warranties, and the co-founders and developers disclaim
* all liability for any vulnerabilities, exploits, errors, or breaches that may occur. By using this interface, users accept all associated
* risks and this disclaimer. The co-founders, developers, or related parties will not bear liability for any consequences of non-compliance.
*
* Redistribution and Use:
* Redistribution, modification, or repurposing of this interface, in whole or in part, is strictly prohibited without express written
* approval from all co-founders. Approval requests must be sent to the official email addresses of the co-founders, ensuring responses
* are received directly from these addresses. Proposals for redistribution, modification, or repurposing must include a detailed explanation
* of the intended changes or uses and the reasons behind them. The co-founders reserve the right to request additional information or
* clarification as necessary. Approval is at the sole discretion of the co-founders and may be subject to conditions to uphold the
* project’s integrity and the values of the Fair Crypto Foundation. Failure to obtain express written approval prior to any redistribution,
* modification, or repurposing will result in a breach of these terms and immediate legal action.
*
* Copyright and License:
* Copyright © 2024 Alixa (Simran Dhillon, Hardev Dhillon, Dayana Plaz). All rights reserved.
* This software is provided 'as is' and may be used by the recipient. No permission is granted for redistribution,
* modification, or repurposing of this interface. Any use beyond the scope defined herein may be subject to legal action.
*/
interface IALX is
IBurnableToken,
IBridgeToken,
IERC20
{
/// -------------------------------------- ERRORS --------------------------------------- \\\
/**
* @notice Error for attempting to mint tokens to the zero address.
* @dev Ensures that token minting is only attempted to valid, non-zero addresses.
*/
error ZeroAddress();
/**
* @notice Error for unauthorised caller.
* @dev Prevents unauthorised access to functions and operations.
*/
error InvalidCaller();
/**
* @notice Error when the Core address has already been set.
* @dev Ensures the Core address can only be set once.
*/
error CoreAlreadySet();
/**
* @notice Error when minting would exceed the max supply.
* @dev Protects against exceeding the predefined maximum supply of ALX tokens.
*/
error ExceedsMaxSupply();
/**
* @notice Error when the max supply cap has been reached.
* @dev Ensures minting operations respect the maximum token supply limit.
*/
error MaxSupplyExceeded();
/**
* @notice Error for invalid claim proof during airdrop claim.
* @dev Validates the Merkle proof for airdrop claims.
*/
error InvalidClaimProof();
/**
* @notice Error for unsupported interface.
* @dev Ensures that only supported interfaces can interact with certain functions.
*/
error UnsupportedInterface();
/**
* @notice Error when airdrop has already been claimed.
* @dev Prevents double claiming of airdrops by users.
*/
error AirdropAlreadyClaimed();
/**
* @notice Error when claiming airdrop outside of the active period.
* @dev Ensures airdrop claims are made within the designated active period.
*/
error AirdropPeriodNotActive();
/// -------------------------------------- EVENTS --------------------------------------- \\\
/**
* @notice Emitted when a user successfully claims their airdrop.
* @dev Logs the user address and the amount of airdrop claimed.
* @param _user Address of the user claiming the airdrop.
* @param _amount Amount of airdrop claimed.
*/
event Airdropped(
address indexed _user,
uint256 _amount
);
/// --------------------------------- EXTERNAL FUNCTIONS -------------------------------- \\\
/**
* @notice Claims airdropped tokens using a Merkle proof.
* @dev Verifies the claim against the Merkle root and mints the tokens.
* @param _proof Array of bytes32 values representing the Merkle proof.
* @param _airdroppedAmount Total airdropped amount.
* @param _amountToClaim Amount of tokens being claimed.
*/
function claim(
bytes32[] calldata _proof,
uint256 _airdroppedAmount,
uint256 _amountToClaim
) external;
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Purchases bonds using airdropped ALX tokens from the first day.
* @dev Verifies the user's airdropped tokens using a Merkle proof.
* @param _proof Array of bytes32 values representing the Merkle proof.
* @param _user Address of the user purchasing bonds.
* @param _bondPower The power of the bond being purchased.
* @param _bondCount The number of bonds to purchase.
* @param _daysCount The duration of the bond in days.
* @param _airdroppedAmount The total amount of airdropped tokens available.
*/
function purchaseBondWithAirdroppedALX(
bytes32[] calldata _proof,
address _user,
uint256 _bondPower,
uint256 _bondCount,
uint256 _daysCount,
uint256 _airdroppedAmount
) external;
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Stakes airdropped ALX tokens within the first 1 day of participation.
* @dev Verifies the user's airdropped tokens using a Merkle proof.
* @param _proof Array of bytes32 values representing the Merkle proof.
* @param _user Address of the user staking tokens.
* @param _duration The duration for which the tokens will be staked.
* @param _amountToStake Amount of tokens being staked.
* @param _airdroppedAmount The total amount of airdropped tokens available.
*/
function stakeWithAirdroppedALX(
bytes32[] calldata _proof,
address _user,
uint256 _duration,
uint256 _amountToStake,
uint256 _airdroppedAmount
) external;
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Mints ALX tokens to a specified account.
* @dev This function allows authorized entities to mint new ALX tokens to a given account.
* @param _account The account to which the tokens will be minted.
* @param _amount The amount of tokens to mint.
*/
function mint(
address _account,
uint256 _amount
) external;
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Burns ALX tokens from a specified user.
* @dev This function allows the burning of ALX tokens from a user's account.
* @param _user The user from whose account tokens will be burned.
* @param _amount The amount of tokens to burn.
*/
function burn(
address _user,
uint256 _amount
) external;
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Sets the ALX-vXNF POL address.
* @dev Can only be set once.
* @param _ALXPOL The address of the ALX-vXNF POL contract.
*/
function setPool(address _ALXPOL) external;
/// ------------------------------------------------------------------------------------- \\\
}
ICore.sol 316 lines
// SPDX-License-Identifier: Unlicensed pragma solidity 0.8.25; /* * @title ICore Interface * * @notice Defines the core functionalities of the Alixa protocol, allowing interaction with bond and staking mechanisms. * * Co-Founders: * - Simran Dhillon: [email protected] * - Hardev Dhillon: [email protected] * - Dayana Plaz: [email protected] * * Official Links: * - Twitter: https://twitter.com/alixa_io * - Telegram: https://t.me/alixa_io * - Website: https://alixa.io * * Disclaimer: * This interface aligns with the principles of the Fair Crypto Foundation, promoting self-custody, transparency, consensus-based * trust, and permissionless value exchange. There are no administrative access keys, underscoring our commitment to decentralisation. * Engaging with this interface involves technical and legal risks. Users must conduct their own due diligence and ensure compliance * with local laws and regulations. The software is provided "AS-IS," without warranties, and the co-founders and developers disclaim * all liability for any vulnerabilities, exploits, errors, or breaches that may occur. By using this interface, users accept all associated * risks and this disclaimer. The co-founders, developers, or related parties will not bear liability for any consequences of non-compliance. * * Redistribution and Use: * Redistribution, modification, or repurposing of this interface, in whole or in part, is strictly prohibited without express written * approval from all co-founders. Approval requests must be sent to the official email addresses of the co-founders, ensuring responses * are received directly from these addresses. Proposals for redistribution, modification, or repurposing must include a detailed explanation * of the intended changes or uses and the reasons behind them. The co-founders reserve the right to request additional information or * clarification as necessary. Approval is at the sole discretion of the co-founders and may be subject to conditions to uphold the * project’s integrity and the values of the Fair Crypto Foundation. Failure to obtain express written approval prior to any redistribution, * modification, or repurposing will result in a breach of these terms and immediate legal action. * * Copyright and License: * Copyright © 2024 Alixa (Simran Dhillon, Hardev Dhillon, Dayana Plaz). All rights reserved. * This software is provided 'as is' and may be used by the recipient. No permission is granted for redistribution, * modification, or repurposing of this interface. Any use beyond the scope defined herein may be subject to legal action. */ interface ICore { /// --------------------------------------- ENUM ---------------------------------------- \\\ /** * @notice Enum representing the types of tokens in the Alixa ecosystem. * @dev The enum contains the supported tokens: eETH, ETHx, and ETH. */ enum Token { eeth, ethx, eth } /// --------------------------------- EXTERNAL FUNCTIONS -------------------------------- \\\ /** * @notice Triggers the provision of assets for liquidity. * @dev This function allows the provision of a specified amount of ALX tokens for liquidity purposes. * @param ALXAmount The amount of ALX tokens to provide for liquidity. */ function provideAssetsForLiquidity(uint256 ALXAmount) external; /// ------------------------------------------------------------------------------------- \\\ /** * @notice Checks if the liquidity provision has been triggered. * @dev This function checks the status of the liquidity provision trigger. * @return bool True if provision has been triggered, false otherwise. */ function isTriggered() external view returns (bool); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Gets the base cost. * @dev Returns the fixed base cost for transactions within the protocol. * @return The base cost value. */ function BASE_COST() external pure returns (uint256); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Calculates and updates the current cycle. * @dev This function is used to calculate the current cycle based on the protocol's parameters * and update the state accordingly. * @return The current cycle number. */ function calculateCycle() external returns (uint256); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Gets the current cycle number. * @dev Returns the current cycle number without modifying the state. * @return The current cycle number. */ function getCurrentCycle() external view returns (uint256); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Calculates the required token amounts for bond operations. * @dev Determines the amount of tokens needed based on bond power and count. Adjusts for ETH bond specifics. * @param _bondPower The power of the bond. * @param _bondCount The number of bonds. * @param _isETHBond Indicates if the bond is an ETH bond. * @return tokenRequired_ The required amount of tokens. */ function getTokenAmounts( uint256 _bondPower, uint256 _bondCount, bool _isETHBond ) external view returns (uint256 tokenRequired_); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Initiates the unbonding process for ALX tokens. * @dev This function initiates the process for unbonding ALX tokens associated with a specific bond ID. * @param _bondID The ID of the bond. * @param _restake Indicates if the rewards should be restaked. */ function unbondingALX( uint256 _bondID, bool _restake ) external; /// ------------------------------------------------------------------------------------- \\\ /** * @notice Reactivating an existing bond. * @dev This function allows reactivating an existing bond with a specified amount of ETHx. * @param _bondID The ID of the bond. * @param _ETHxAmount The amount of ETHx to use in the reactivation. */ function reactivate( uint256 _bondID, uint256 _ETHxAmount ) external; /// ------------------------------------------------------------------------------------- \\\ /** * @notice Claims ETHx rewards for a bond. * @dev This function claims the ETHx rewards associated with a specific bond ID. * @param _bondID The ID of the bond. * @param _restake Indicates if the rewards should be restaked. */ function claimETHxRewards( uint256 _bondID, bool _restake ) external; /// ------------------------------------------------------------------------------------- \\\ /** * @notice Gets the pending ALX rewards for a bond. * @dev This function returns the amount of pending ALX rewards for a specific bond ID. * @param _bondID The ID of the bond. * @return reward_ The amount of pending ALX rewards. */ function pendingALX(uint256 _bondID) external view returns (uint256 reward_); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Checks if a bond exists. * @dev This function checks if a bond exists for a specific user and bond ID. * @param _user The address of the user. * @param _bondID The ID of the bond. * @return exists_ True if the bond exists, false otherwise. */ function isExist( address _user, uint256 _bondID ) external view returns (bool exists_); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Transfers a bond to a new owner. * @dev This function transfers the ownership of specified bonds to a new recipient. * @param _bondIDs The IDs of the bonds to transfer. * @param _recipient The recipient of the bond transfer. * @param _restake Indicates if the rewards should be restaked. */ function transferBond( uint256[] calldata _bondIDs, address _recipient, bool _restake ) external; /// ------------------------------------------------------------------------------------- \\\ /** * @notice Allows a user to snipe a bond. * @dev This function allows a user to snipe a bond by providing the bond IDs of the user and the sniper. * @param _user The address of the bond owner. * @param _bondIDUser The ID of the bond to snipe. * @param _bondIDSniper The ID of the sniper's bond. * @param _restake Indicates if the rewards should be restaked. */ function snipe( address _user, uint256 _bondIDUser, uint256 _bondIDSniper, bool _restake ) external; /// ------------------------------------------------------------------------------------- \\\ /** * @notice Calculates pending ETHx rewards for a bond. * @dev This function calculates the pending ETHx rewards for a specific bond ID. * @param _user The address of the user. * @param _bondID The ID of the bond. * @return pendingAmount_ The pending amount of ETHx rewards. * @return pendingBonus_ The pending bonus amount. * @return totalPending_ The total pending rewards. */ function pendingETHx( address _user, uint256 _bondID ) external view returns ( uint256 pendingAmount_, uint256 pendingBonus_, uint256 totalPending_ ); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Allows a user to purchase a bond with ALX. * @dev This function allows a user to purchase a bond using ALX tokens. * @param _user The address of the user. * @param _bondCount The number of bonds to purchase. * @param _daysCount The number of days for the bond. * @param _bondPower The power of the bond. */ function purchaseALXBond( address _user, uint256 _bondCount, uint256 _daysCount, uint256 _bondPower ) external; /// ------------------------------------------------------------------------------------- \\\ /** * @notice Purchase a bond with ALX tokens that are airdropped. * @dev Allows users to purchase bonds using their airdropped ALX tokens. * @param _user Address of the user purchasing the bond. * @param _bondCount Number of bonds to purchase. * @param _daysCount Number of days until bond maturity. * @param _bondPower The power rating of the bond. * @param _requiredALXAmount The amount of ALX that is needed to purchase a bond. */ function purchaseBondWithAirdroppedALX( address _user, uint256 _bondCount, uint256 _daysCount, uint256 _bondPower, uint256 _requiredALXAmount ) external payable; /// ------------------------------------------------------------------------------------- \\\ /** * @notice Allows a user to purchase an ETH bond. * @dev This function allows a user to purchase a bond using ETH or ETH-based tokens. * @param _user The address of the user. * @param _bondCount The number of bonds to purchase. * @param _token The type of token used for the purchase. * @param _daysCount The number of days for the bond. * @param _bondPower The power of the bond. */ function purchaseETHBond( address _user, uint256 _bondCount, Token _token, uint256 _daysCount, uint256 _bondPower ) external payable; /// ------------------------------------------------------------------------------------- \\\ }
IvXNF.sol 198 lines
// SPDX-License-Identifier: Unlicensed
pragma solidity 0.8.25;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IBurnableToken} from "./IBurnableToken.sol";
import {IBridgeToken} from "./IBridgeToken.sol";
/*
* @title vXNF Contract
*
* @notice This interface outlines functions for the vXNF token, an ERC20 token with bridging and burning capabilities.
*
* Co-Founders:
* - Simran Dhillon: [email protected]
* - Hardev Dhillon: [email protected]
* - Dayana Plaz: [email protected]
*
* Official Links:
* - Twitter: https://twitter.com/xenify_io
* - Telegram: https://t.me/xenify_io
* - Website: https://xenify.io
*
* Disclaimer:
* This contract aligns with the principles of the Fair Crypto Foundation, promoting self-custody, transparency, consensus-based
* trust, and permissionless value exchange. There are no administrative access keys, underscoring our commitment to decentralization.
* Engaging with this contract involves technical and legal risks. Users must conduct their own due diligence and ensure compliance
* with local laws and regulations. The software is provided "AS-IS," without warranties, and the co-founders and developers disclaim
* all liability for any vulnerabilities, exploits, errors, or breaches that may occur. By using this contract, users accept all associated
* risks and this disclaimer. The co-founders, developers, or related parties will not bear liability for any consequences of non-compliance.
*
* Redistribution and Use:
* Redistribution, modification, or repurposing of this contract, in whole or in part, is strictly prohibited without express written
* approval from all co-founders. Approval requests must be sent to the official email addresses of the co-founders, ensuring responses
* are received directly from these addresses. Proposals for redistribution, modification, or repurposing must include a detailed explanation
* of the intended changes or uses and the reasons behind them. The co-founders reserve the right to request additional information or
* clarification as necessary. Approval is at the sole discretion of the co-founders and may be subject to conditions to uphold the
* project’s integrity and the values of the Fair Crypto Foundation. Failure to obtain express written approval prior to any redistribution,
* modification, or repurposing will result in a breach of these terms and immediate legal action.
*
* Copyright and License:
* Copyright © 2023 Xenify (Simran Dhillon, Hardev Dhillon, Dayana Plaz). All rights reserved.
* This software is provided 'as is' and may be used by the recipient. No permission is granted for redistribution,
* modification, or repurposing of this contract. Any use beyond the scope defined herein may be subject to legal action.
*/
interface IvXNF is
IBurnableToken,
IBridgeToken,
IERC20
{
/// -------------------------------------- ERRORS --------------------------------------- \\\
/**
* @notice This error is thrown when only the team is allowed to call a function.
*/
error OnlyTeamAllowed();
/**
* @notice This error is thrown when XNF address is already set.
*/
error XNFIsAlreadySet();
/// -------------------------------------- EVENTS --------------------------------------- \\\
/**
* @notice Emitted when vXNF tokens are bridged to another chain.
* @param _from Address on the source chain that initiated the bridge.
* @param _burnedAmount Amount of vXNF tokens burned for the bridge.
* @param _bridgeId Identifier for the bridge used
* @param _outgoingChainId ID of the destination chain.
* @param _to Address on the destination chain to receive the tokens.
*/
event vXNFBridgeTransfer(
address indexed _from,
uint256 _burnedAmount,
BridgeId indexed _bridgeId,
bytes _outgoingChainId,
address indexed _to
);
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Emitted when vXNF tokens are received from a bridge.
* @param _to Address that receives the minted vXNF tokens.
* @param _mintAmount Amount of vXNF tokens minted.
* @param _bridgeId Identifier for the bridge used
* @param _incomingChainId ID of the source chain.
* @param _from Address on the source chain that initiated the bridge.
*/
event vXNFBridgeReceive(
address indexed _to,
uint256 _mintAmount,
BridgeId indexed _bridgeId,
bytes _incomingChainId,
address indexed _from
);
/// --------------------------------- EXTERNAL FUNCTIONS -------------------------------- \\\
/**
* @notice Sets the XNF contract address.
* @dev This function is called by the team to set XNF contract address.
* Function can be called only once.
* @param _XNF The XNF contract address.
* @param _ratio The ratio between vXNF and XNF used for minting and burning.
*/
function setXNFAndRatio(
address _XNF,
uint256 _ratio
) external;
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Burns the specified amount of XNF tokens and mints an equivalent amount of vXNF tokens.
* @param _amount Amount of XNF tokens to burn.
*/
function burnXNF(uint256 _amount) external;
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Burns the specified amount of XNF tokens and bridges them via the LayerZero network.
* @dev Burns the XNF tokens from the sender's address and then initiates a bridge operation using the LayerZero network.
* @param _amount The amount of XNF tokens to burn and bridge.
* @param _dstChainId The Chain ID of the destination chain on the LayerZero network.
* @param _to The recipient address on the destination chain.
* @param _feeRefundAddress Address to refund any excess fees.
* @param _zroPaymentAddress Address of the ZRO token holder who would pay for the transaction.
* @param _adapterParams Parameters for custom functionality, e.g., receiving airdropped native gas from the relayer on the destination.
*/
function burnAndBridgeViaLayerZero(
uint256 _amount,
uint16 _dstChainId,
address _to,
address payable _feeRefundAddress,
address _zroPaymentAddress,
bytes calldata _adapterParams
)
external
payable;
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Burns the specified amount of XNF tokens and bridges them via the Axelar network.
* @dev Burns the XNF tokens from the sender's address and then initiates a bridge operation using the Axelar network.
* @param _amount The amount of XNF tokens to burn and bridge.
* @param _dstChainId The target chain where tokens should be bridged to on the Axelar network.
* @param _to The recipient address on the destination chain.
* @param _feeRefundAddress Address to refund any excess fees.
*/
function burnAndBridgeViaAxelar(
uint256 _amount,
string calldata _dstChainId,
address _to,
address payable _feeRefundAddress
)
external
payable;
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Burns the specified amount of XNF tokens and bridges them via the Wormhole network.
* @dev Burns the XNF tokens from the sender's address and then initiates a bridge operation using the Wormhole network.
* @param _amount The amount of XNF tokens to burn and bridge.
* @param _targetChain The ID of the target chain on the Wormhole network.
* @param _to The recipient address on the destination chain.
* @param _feeRefundAddress Address to refund any excess fees.
* @param _gasLimit The gas limit for the transaction on the destination chain.
*/
function burnAndBridgeViaWormhole(
uint256 _amount,
uint16 _targetChain,
address _to,
address payable _feeRefundAddress,
uint256 _gasLimit
)
external
payable;
/// ------------------------------------------------------------------------------------- \\\
/**
* @notice Burns a specific amount of vXNF tokens from a user's address.
* @dev Allows an external entity to burn tokens from a user's address, provided they have the necessary allowance.
* @param _user The address from which the vXNF tokens will be burned.
* @param _amount The amount of vXNF tokens to burn.
*/
function burn(
address _user,
uint256 _amount
) external;
/// ------------------------------------------------------------------------------------- \\\
}
IBridgeToken.sol 298 lines
// SPDX-License-Identifier: Unlicensed pragma solidity 0.8.25; /* * @title IBridge Interface * * @notice Interface defining the functions and events for token bridging operations. * * Co-Founders: * - Simran Dhillon: [email protected] * - Hardev Dhillon: [email protected] * - Dayana Plaz: [email protected] * * Official Links: * - Twitter: https://twitter.com/alixa_io * - Telegram: https://t.me/alixa_io * - Website: https://alixa.io * * Disclaimer: * This interface aligns with the principles of the Fair Crypto Foundation, promoting self-custody, transparency, consensus-based * trust, and permissionless value exchange. There are no administrative access keys, underscoring our commitment to decentralisation. * Engaging with this interface involves technical and legal risks. Users must conduct their own due diligence and ensure compliance * with local laws and regulations. The software is provided "AS-IS," without warranties, and the co-founders and developers disclaim * all liability for any vulnerabilities, exploits, errors, or breaches that may occur. By using this interface, users accept all associated * risks and this disclaimer. The co-founders, developers, or related parties will not bear liability for any consequences of non-compliance. * * Redistribution and Use: * Redistribution, modification, or repurposing of this interface, in whole or in part, is strictly prohibited without express written * approval from all co-founders. Approval requests must be sent to the official email addresses of the co-founders, ensuring responses * are received directly from these addresses. Proposals for redistribution, modification, or repurposing must include a detailed explanation * of the intended changes or uses and the reasons behind them. The co-founders reserve the right to request additional information or * clarification as necessary. Approval is at the sole discretion of the co-founders and may be subject to conditions to uphold the * project’s integrity and the values of the Fair Crypto Foundation. Failure to obtain express written approval prior to any redistribution, * modification, or repurposing will result in a breach of these terms and immediate legal action. * * Copyright and License: * Copyright © 2024 Alixa (Simran Dhillon, Hardev Dhillon, Dayana Plaz). All rights reserved. * This software is provided 'as is' and may be used by the recipient. No permission is granted for redistribution, * modification, or repurposing of this interface. Any use beyond the scope defined herein may be subject to legal action. */ interface IBridgeToken { /// --------------------------------------- ENUM ---------------------------------------- \\\ /** * @notice Enumerates the types of bridges supported. * @dev Defines the different bridge protocols that can be used for cross-chain operations. */ enum BridgeId { LayerZero, Wormhole, Axelar } /// -------------------------------------- EVENTS --------------------------------------- \\\ /** * @notice Emitted when tokens are received through a bridge. * @dev Logs the receipt of tokens bridged from another chain. * @param to Recipient address. * @param amount Amount of tokens received. * @param bridgeId Identifier of the bridge used. * @param fromChainId Identifier of the source chain. * @param from Sender address on the source chain. */ event BridgeReceive( address indexed to, uint256 amount, BridgeId bridgeId, bytes fromChainId, address indexed from ); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Emitted when tokens are sent to another chain via a bridge. * @dev Logs the transfer of tokens to another chain. * @param from Sender address. * @param amount Amount of tokens transferred. * @param bridgeId Bridge used for the transfer. * @param toChainId Destination chain identifier. * @param to Recipient address on the destination chain. */ event BridgeTransfer( address indexed from, uint256 amount, BridgeId bridgeId, bytes toChainId, address indexed to ); /// -------------------------------------- ERRORS --------------------------------------- \\\ /** * @notice Error for when the provided fee is insufficient. * @dev Ensures the user provides enough fee for the bridging operation. */ error InsufficientFee(); /** * @notice Error for when the recipient address is invalid. * @dev Validates the recipient address in bridging operations. */ error InvalidToAddress(); /** * @notice Error for when a non-verified caller attempts an operation. * @dev Prevents unauthorised access to bridge functions. */ error NotVerifiedCaller(); /** * @notice Error indicating that the operation is restricted to the relayer. * @dev Ensures only the designated relayer can perform certain operations. */ error OnlyRelayerAllowed(); /** * @notice Error for when the source address is invalid. * @dev Validates the source address in bridging operations. */ error InvalidSourceAddress(); /** * @notice Error for when the fee for Wormhole bridging is insufficient. * @dev Ensures the user provides enough fee for the Wormhole bridging operation. */ error InsufficientFeeForWormhole(); /** * @notice Error for when the Wormhole source address is invalid. * @dev Validates the source address in Wormhole bridging operations. */ error InvalidWormholeSourceAddress(); /** * @notice Error for when the LayerZero source address is invalid. * @dev Validates the source address in LayerZero bridging operations. */ error InvalidLayerZeroSourceAddress(); /** * @notice Error for when a Wormhole message is replayed. * @dev Prevents replay attacks in Wormhole bridging operations. */ error WormholeMessageAlreadyProcessed(); /// --------------------------------- EXTERNAL FUNCTIONS -------------------------------- \\\ /** * @notice Receives tokens via LayerZero. * @dev Handles incoming tokens from LayerZero bridging operations. * @param _srcChainId The Chain ID of the source chain on the LayerZero network. * @param _srcAddress The address on the source chain from which the ALX tokens were sent. * @param _payload The encoded data containing details about the bridging operation, including the recipient address and amount. */ function lzReceive( uint16 _srcChainId, bytes memory _srcAddress, uint64, bytes memory _payload ) external; /// ------------------------------------------------------------------------------------- \\\ /** * @notice Receives tokens via Wormhole. * @dev Handles incoming tokens from Wormhole bridging operations. * @param _payload The encoded data containing user address and amount. * @param _sourceAddress The address of the caller on the source chain in bytes32. * @param _srcChainId The chain ID of the source chain from which the tokens are being bridged. * @param _deliveryHash The hash which is used to verify relay calls. */ function receiveWormholeMessages( bytes memory _payload, bytes[] memory, bytes32 _sourceAddress, uint16 _srcChainId, bytes32 _deliveryHash ) external payable; /// ------------------------------------------------------------------------------------- \\\ /** * @notice Bridges tokens to another chain via LayerZero. * @dev Facilitates token transfer to another chain using LayerZero bridging. * @param _dstChainId ID of the target chain on LayerZero. * @param _from Sender's address on the source chain. * @param _to Recipient's address on the destination chain. * @param _amount Amount of tokens to bridge. * @param _feeRefundAddress Address for any excess fee refunds. * @param _zroPaymentAddress Address of the ZRO token holder covering transaction fees. * @param _adapterParams Additional parameters for custom functionalities. */ function bridgeViaLayerZero( uint16 _dstChainId, address _from, address _to, uint256 _amount, address payable _feeRefundAddress, address _zroPaymentAddress, bytes calldata _adapterParams ) external payable; /// ------------------------------------------------------------------------------------- \\\ /** * @notice Bridges tokens to another chain via Axelar. * @dev Facilitates token transfer to another chain using Axelar bridging. * @param _destinationChain ID of the target chain on Axelar. * @param _from Sender's address on the source chain. * @param _to Recipient's address on the destination chain. * @param _amount Amount of tokens to bridge. * @param _feeRefundAddress Address for any excess fee refunds. */ function bridgeViaAxelar( string calldata _destinationChain, address _from, address _to, uint256 _amount, address payable _feeRefundAddress ) external payable; /// ------------------------------------------------------------------------------------- \\\ /** * @notice Bridges tokens to another chain via Wormhole. * @dev Facilitates token transfer to another chain using Wormhole bridging. * @param _targetChain ID of the target chain on Wormhole. * @param _from Sender's address on the source chain. * @param _to Recipient's address on the destination chain. * @param _amount Amount of tokens to bridge. * @param _feeRefundAddress Address for any excess fee refunds. * @param _gasLimit Gas limit for the transaction on the destination chain. */ function bridgeViaWormhole( uint16 _targetChain, address _from, address _to, uint256 _amount, address payable _feeRefundAddress, uint256 _gasLimit ) external payable; /// ------------------------------------------------------------------------------------- \\\ /** * @notice Estimates the gas required for LayerZero bridging. * @dev Provides an estimate of the gas fee needed for LayerZero bridging operations. * @param _dstChainId ID of the destination chain on LayerZero. * @param _from Sender's address on the source chain. * @param _to Recipient's address on the destination chain. * @param _amount Amount of tokens to bridge. * @param _payInZRO If false, user pays the fee in native token. * @param _adapterParam Parameters for adapter services. * @return nativeFee_ Estimated fee in native tokens. */ function estimateGasForLayerZero( uint16 _dstChainId, address _from, address _to, uint256 _amount, bool _payInZRO, bytes calldata _adapterParam ) external view returns (uint256 nativeFee_); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Estimates the gas required for Wormhole bridging. * @dev Provides an estimate of the gas fee needed for Wormhole bridging operations. * @param _targetChain ID of the destination chain on Wormhole. * @param _gasLimit Gas limit for the transaction on the destination chain. * @return cost_ Estimated fee for the operation. */ function estimateGasForWormhole( uint16 _targetChain, uint256 _gasLimit ) external view returns (uint256 cost_); /// ------------------------------------------------------------------------------------- \\\ }
IBurnableToken.sol 59 lines
// SPDX-License-Identifier: Unlicensed pragma solidity 0.8.25; /* * @title IBurnableToken Interface * * @notice Defines the functionality for tokens that can be burned, reducing the total supply irreversibly. * * Co-Founders: * - Simran Dhillon: [email protected] * - Hardev Dhillon: [email protected] * - Dayana Plaz: [email protected] * * Official Links: * - Twitter: https://twitter.com/alixa_io * - Telegram: https://t.me/alixa_io * - Website: https://alixa.io * * Disclaimer: * This interface aligns with the principles of the Fair Crypto Foundation, promoting self-custody, transparency, consensus-based * trust, and permissionless value exchange. There are no administrative access keys, underscoring our commitment to decentralisation. * Engaging with this interface involves technical and legal risks. Users must conduct their own due diligence and ensure compliance * with local laws and regulations. The software is provided "AS-IS," without warranties, and the co-founders and developers disclaim * all liability for any vulnerabilities, exploits, errors, or breaches that may occur. By using this interface, users accept all associated * risks and this disclaimer. The co-founders, developers, or related parties will not bear liability for any consequences of non-compliance. * * Redistribution and Use: * Redistribution, modification, or repurposing of this interface, in whole or in part, is strictly prohibited without express written * approval from all co-founders. Approval requests must be sent to the official email addresses of the co-founders, ensuring responses * are received directly from these addresses. Proposals for redistribution, modification, or repurposing must include a detailed explanation * of the intended changes or uses and the reasons behind them. The co-founders reserve the right to request additional information or * clarification as necessary. Approval is at the sole discretion of the co-founders and may be subject to conditions to uphold the * project’s integrity and the values of the Fair Crypto Foundation. Failure to obtain express written approval prior to any redistribution, * modification, or repurposing will result in a breach of these terms and immediate legal action. * * Copyright and License: * Copyright © 2024 Alixa (Simran Dhillon, Hardev Dhillon, Dayana Plaz). All rights reserved. * This software is provided 'as is' and may be used by the recipient. No permission is granted for redistribution, * modification, or repurposing of this interface. Any use beyond the scope defined herein may be subject to legal action. */ interface IBurnableToken { /// --------------------------------- EXTERNAL FUNCTION --------------------------------- \\\ /** * @notice Burns a specific amount of tokens from a user's account. * @dev Reduces the total supply by destroying the specified amount of tokens from the user's balance. * Ensures the user has sufficient balance and emits a Transfer event to the zero address. * @param _user The address from which the tokens will be burned. * @param _amount The number of tokens to be burned. */ function burn( address _user, uint256 _amount ) external; /// ------------------------------------------------------------------------------------- \\\ }
IBurnRedeemable.sol 59 lines
// SPDX-License-Identifier: Unlicensed pragma solidity 0.8.25; /* * @title IBurnRedeemable Interface * * @notice Interface for tokens with redeemable features upon burning. * * Co-Founders: * - Simran Dhillon: [email protected] * - Hardev Dhillon: [email protected] * - Dayana Plaz: [email protected] * * Official Links: * - Twitter: https://twitter.com/alixa_io * - Telegram: https://t.me/alixa_io * - Website: https://alixa.io * * Disclaimer: * This interface aligns with the principles of the Fair Crypto Foundation, promoting self-custody, transparency, consensus-based * trust, and permissionless value exchange. There are no administrative access keys, underscoring our commitment to decentralisation. * Engaging with this interface involves technical and legal risks. Users must conduct their own due diligence and ensure compliance * with local laws and regulations. The software is provided "AS-IS," without warranties, and the co-founders and developers disclaim * all liability for any vulnerabilities, exploits, errors, or breaches that may occur. By using this interface, users accept all associated * risks and this disclaimer. The co-founders, developers, or related parties will not bear liability for any consequences of non-compliance. * * Redistribution and Use: * Redistribution, modification, or repurposing of this interface, in whole or in part, is strictly prohibited without express written * approval from all co-founders. Approval requests must be sent to the official email addresses of the co-founders, ensuring responses * are received directly from these addresses. Proposals for redistribution, modification, or repurposing must include a detailed explanation * of the intended changes or uses and the reasons behind them. The co-founders reserve the right to request additional information or * clarification as necessary. Approval is at the sole discretion of the co-founders and may be subject to conditions to uphold the * project’s integrity and the values of the Fair Crypto Foundation. Failure to obtain express written approval prior to any redistribution, * modification, or repurposing will result in a breach of these terms and immediate legal action. * * Copyright and License: * Copyright © 2024 Alixa (Simran Dhillon, Hardev Dhillon, Dayana Plaz). All rights reserved. * This software is provided 'as is' and may be used by the recipient. No permission is granted for redistribution, * modification, or repurposing of this interface. Any use beyond the scope defined herein may be subject to legal action. */ interface IBurnRedeemable { /// --------------------------------- EXTERNAL FUNCTION --------------------------------- \\\ /** * @notice Triggered when a user burns tokens. * @dev This function should include any additional logic that needs to occur when tokens are burned, such as redemption processes. * Implementers should guard against reentrancy attacks where necessary. * @param _user The address of the user who is burning the tokens. * @param _amount The amount of tokens being burned. */ function onTokenBurned( address _user, uint256 _amount ) external; /// ------------------------------------------------------------------------------------- \\\ }
Context.sol 28 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
IWormholeRelayer.sol 911 lines
// SPDX-License-Identifier: Unlicensed pragma solidity 0.8.25; /* * @title IWormholeRelayerBase Interface * * @notice Defines the base interface for the Wormhole Relayer, facilitating cross-chain communication and message relaying. * * Co-Founders: * - Simran Dhillon: [email protected] * - Hardev Dhillon: [email protected] * - Dayana Plaz: [email protected] * * Official Links: * - Twitter: https://twitter.com/alixa_io * - Telegram: https://t.me/alixa_io * - Website: https://alixa.io * * Disclaimer: * This interface aligns with the principles of the Fair Crypto Foundation, promoting self-custody, transparency, consensus-based * trust, and permissionless value exchange. There are no administrative access keys, underscoring our commitment to decentralisation. * Engaging with this interface involves technical and legal risks. Users must conduct their own due diligence and ensure compliance * with local laws and regulations. The software is provided "AS-IS," without warranties, and the co-founders and developers disclaim * all liability for any vulnerabilities, exploits, errors, or breaches that may occur. By using this interface, users accept all associated * risks and this disclaimer. The co-founders, developers, or related parties will not bear liability for any consequences of non-compliance. * * Redistribution and Use: * Redistribution, modification, or repurposing of this interface, in whole or in part, is strictly prohibited without express written * approval from all co-founders. Approval requests must be sent to the official email addresses of the co-founders, ensuring responses * are received directly from these addresses. Proposals for redistribution, modification, or repurposing must include a detailed explanation * of the intended changes or uses and the reasons behind them. The co-founders reserve the right to request additional information or * clarification as necessary. Approval is at the sole discretion of the co-founders and may be subject to conditions to uphold the * project’s integrity and the values of the Fair Crypto Foundation. Failure to obtain express written approval prior to any redistribution, * modification, or repurposing will result in a breach of these terms and immediate legal action. * * Copyright and License: * Copyright © 2024 Alixa (Simran Dhillon, Hardev Dhillon, Dayana Plaz). All rights reserved. * This software is provided 'as is' and may be used by the recipient. No permission is granted for redistribution, * modification, or repurposing of this interface. Any use beyond the scope defined herein may be subject to legal action. */ /// ------------------------------------- STRUCTURE ------------------------------------- \\\ /** * @notice VaaKey identifies a wormhole message. * @custom:member chainId Wormhole chain ID of the chain where this VAA was emitted from. * @custom:member emitterAddress Address of the emitter of the VAA, in Wormhole bytes32 format. * @custom:member sequence Sequence number of the VAA. */ struct VaaKey { uint16 chainId; bytes32 emitterAddress; uint64 sequence; } /// ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| \\\ /** * @title IWormholeRelayerBase * @notice Interface for basic Wormhole Relayer operations. */ interface IWormholeRelayerBase { /// -------------------------------------- EVENT ---------------------------------------- \\\ /** * @notice Emitted when a Send operation is executed. * @param sequence The sequence of the send event. * @param deliveryQuote The delivery quote for the send operation. * @param paymentForExtraReceiverValue The payment value for the additional receiver. */ event SendEvent( uint64 indexed sequence, uint256 deliveryQuote, uint256 paymentForExtraReceiverValue ); /// --------------------------------- EXTERNAL FUNCTION --------------------------------- \\\ /** * @notice Fetches the registered Wormhole Relayer contract for a given chain ID. * @param chainId The chain ID to fetch the relayer contract for. * @return The address of the registered Wormhole Relayer contract for the given chain ID. */ function getRegisteredWormholeRelayerContract(uint16 chainId) external view returns (bytes32); /// ------------------------------------------------------------------------------------- \\\ } /// ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| \\\ /** * @title IWormholeRelayerSend * @notice The interface to request deliveries. */ interface IWormholeRelayerSend is IWormholeRelayerBase { /// --------------------------------- EXTERNAL FUNCTIONS -------------------------------- \\\ /** * @notice Publishes an instruction for the default delivery provider * to relay a payload to the address `targetAddress` on chain `targetChain` * with gas limit `gasLimit` and `msg.value` equal to `receiverValue` * * `targetAddress` must implement the IWormholeReceiver interface. * * This function must be called with `msg.value` equal to `quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit)`. * * Any refunds (from leftover gas) will be paid to the delivery provider. In order to receive the refunds, use the `sendPayloadToEvm` function * with `refundChain` and `refundAddress` as parameters. * * @param targetChain in Wormhole Chain ID format. * @param targetAddress address to call on targetChain (that implements IWormholeReceiver). * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress`. * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units). * @param gasLimit gas limit with which to call `targetAddress`. * @return sequence sequence number of published VAA containing delivery instructions. */ function sendPayloadToEvm( uint16 targetChain, address targetAddress, bytes memory payload, uint256 receiverValue, uint256 gasLimit ) external payable returns (uint64 sequence); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Publishes an instruction for the default delivery provider. * to relay a payload to the address `targetAddress` on chain `targetChain` * with gas limit `gasLimit` and `msg.value` equal to `receiverValue`. * * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain` * `targetAddress` must implement the IWormholeReceiver interface. * * This function must be called with `msg.value` equal to `quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit)`. * * @param targetChain in Wormhole Chain ID format. * @param targetAddress address to call on targetChain (that implements IWormholeReceiver). * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress`. * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units). * @param gasLimit gas limit with which to call `targetAddress`. Any units of gas unused will be refunded according to the * `targetChainRefundPerGasUnused` rate quoted by the delivery provider. * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format. * @param refundAddress The address on `refundChain` to deliver any refund to. * @return sequence sequence number of published VAA containing delivery instructions. */ function sendPayloadToEvm( uint16 targetChain, address targetAddress, bytes memory payload, uint256 receiverValue, uint256 gasLimit, uint16 refundChain, address refundAddress ) external payable returns (uint64 sequence); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Publishes an instruction for the default delivery provider * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain` * with gas limit `gasLimit` and `msg.value` equal to `receiverValue` * * `targetAddress` must implement the IWormholeReceiver interface * * This function must be called with `msg.value` equal to `quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit)` * * Any refunds (from leftover gas) will be paid to the delivery provider. In order to receive the refunds, use the `sendVaasToEvm` function * with `refundChain` and `refundAddress` as parameters * * @param targetChain in Wormhole Chain ID format * @param targetAddress address to call on targetChain (that implements IWormholeReceiver) * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress` * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param gasLimit gas limit with which to call `targetAddress`. * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress` * @return sequence sequence number of published VAA containing delivery instructions */ function sendVaasToEvm( uint16 targetChain, address targetAddress, bytes memory payload, uint256 receiverValue, uint256 gasLimit, VaaKey[] memory vaaKeys ) external payable returns (uint64 sequence); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Publishes an instruction for the default delivery provider * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain` * with gas limit `gasLimit` and `msg.value` equal to `receiverValue` * * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain` * `targetAddress` must implement the IWormholeReceiver interface * * This function must be called with `msg.value` equal to `quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit)` * * @param targetChain in Wormhole Chain ID format * @param targetAddress address to call on targetChain (that implements IWormholeReceiver) * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress` * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param gasLimit gas limit with which to call `targetAddress`. Any units of gas unused will be refunded according to the * `targetChainRefundPerGasUnused` rate quoted by the delivery provider * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress` * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format * @param refundAddress The address on `refundChain` to deliver any refund to * @return sequence sequence number of published VAA containing delivery instructions */ function sendVaasToEvm( uint16 targetChain, address targetAddress, bytes memory payload, uint256 receiverValue, uint256 gasLimit, VaaKey[] memory vaaKeys, uint16 refundChain, address refundAddress ) external payable returns (uint64 sequence); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Publishes an instruction for the delivery provider at `deliveryProviderAddress` * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain` * with gas limit `gasLimit` and `msg.value` equal to * receiverValue + (arbitrary amount that is paid for by paymentForExtraReceiverValue of this chain's wei) in targetChain wei. * * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain` * `targetAddress` must implement the IWormholeReceiver interface * * This function must be called with `msg.value` equal to * quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit, deliveryProviderAddress) + paymentForExtraReceiverValue * * @param targetChain in Wormhole Chain ID format * @param targetAddress address to call on targetChain (that implements IWormholeReceiver) * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress` * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param paymentForExtraReceiverValue amount (in current chain currency units) to spend on extra receiverValue * (in addition to the `receiverValue` specified) * @param gasLimit gas limit with which to call `targetAddress`. Any units of gas unused will be refunded according to the * `targetChainRefundPerGasUnused` rate quoted by the delivery provider * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format * @param refundAddress The address on `refundChain` to deliver any refund to * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress` * @param consistencyLevel Consistency level with which to publish the delivery instructions - see * https://book.wormhole.com/wormhole/3_coreLayerContracts.html?highlight=consistency#consistency-levels * @return sequence sequence number of published VAA containing delivery instructions */ function sendToEvm( uint16 targetChain, address targetAddress, bytes memory payload, uint256 receiverValue, uint256 paymentForExtraReceiverValue, uint256 gasLimit, uint16 refundChain, address refundAddress, address deliveryProviderAddress, VaaKey[] memory vaaKeys, uint8 consistencyLevel ) external payable returns (uint64 sequence); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Publishes an instruction for the delivery provider at `deliveryProviderAddress` * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain` * with `msg.value` equal to * receiverValue + (arbitrary amount that is paid for by paymentForExtraReceiverValue of this chain's wei) in targetChain wei. * * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain` * `targetAddress` must implement the IWormholeReceiver interface * * This function must be called with `msg.value` equal to * quoteDeliveryPrice(targetChain, receiverValue, encodedExecutionParameters, deliveryProviderAddress) + paymentForExtraReceiverValue * * @param targetChain in Wormhole Chain ID format * @param targetAddress address to call on targetChain (that implements IWormholeReceiver), in Wormhole bytes32 format * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress` * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param paymentForExtraReceiverValue amount (in current chain currency units) to spend on extra receiverValue * (in addition to the `receiverValue` specified) * @param encodedExecutionParameters encoded information on how to execute delivery that may impact pricing * e.g. for version EVM_V1, this is a struct that encodes the `gasLimit` with which to call `targetAddress` * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format * @param refundAddress The address on `refundChain` to deliver any refund to, in Wormhole bytes32 format * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress` * @param consistencyLevel Consistency level with which to publish the delivery instructions - see * https://book.wormhole.com/wormhole/3_coreLayerContracts.html?highlight=consistency#consistency-levels * @return sequence sequence number of published VAA containing delivery instructions */ function send( uint16 targetChain, bytes32 targetAddress, bytes memory payload, uint256 receiverValue, uint256 paymentForExtraReceiverValue, bytes memory encodedExecutionParameters, uint16 refundChain, bytes32 refundAddress, address deliveryProviderAddress, VaaKey[] memory vaaKeys, uint8 consistencyLevel ) external payable returns (uint64 sequence); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Performs the same function as a `send`, except: * 1) Can only be used during a delivery (i.e. in execution of `receiveWormholeMessages`) * 2) Is paid for (along with any other calls to forward) by (any msg.value passed in) + (refund leftover from current delivery) * 3) Only executes after `receiveWormholeMessages` is completed (and thus does not return a sequence number) * * The refund from the delivery currently in progress will not be sent to the user; it will instead * be paid to the delivery provider to perform the instruction specified here * * Publishes an instruction for the same delivery provider (or default, if the same one doesn't support the new target chain) * to relay a payload to the address `targetAddress` on chain `targetChain` * with gas limit `gasLimit` and with `msg.value` equal to `receiverValue` * * The following equation must be satisfied (sum_f indicates summing over all forwards requested in `receiveWormholeMessages`): * (refund amount from current execution of receiveWormholeMessages) + sum_f [msg.value_f] * >= sum_f [quoteEVMDeliveryPrice(targetChain_f, receiverValue_f, gasLimit_f)] * * The difference between the two sides of the above inequality will be added to `paymentForExtraReceiverValue` of the first forward requested * * Any refunds (from leftover gas) from this forward will be paid to the same refundChain and refundAddress specified for the current delivery. * * @param targetChain in Wormhole Chain ID format * @param targetAddress address to call on targetChain (that implements IWormholeReceiver), in Wormhole bytes32 format * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress` * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param gasLimit gas limit with which to call `targetAddress`. */ function forwardPayloadToEvm( uint16 targetChain, address targetAddress, bytes memory payload, uint256 receiverValue, uint256 gasLimit ) external payable; /// ------------------------------------------------------------------------------------- \\\ /** * @notice Performs the same function as a `send`, except: * 1) Can only be used during a delivery (i.e. in execution of `receiveWormholeMessages`) * 2) Is paid for (along with any other calls to forward) by (any msg.value passed in) + (refund leftover from current delivery) * 3) Only executes after `receiveWormholeMessages` is completed (and thus does not return a sequence number) * * The refund from the delivery currently in progress will not be sent to the user; it will instead * be paid to the delivery provider to perform the instruction specified here * * Publishes an instruction for the same delivery provider (or default, if the same one doesn't support the new target chain) * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain` * with gas limit `gasLimit` and with `msg.value` equal to `receiverValue` * * The following equation must be satisfied (sum_f indicates summing over all forwards requested in `receiveWormholeMessages`): * (refund amount from current execution of receiveWormholeMessages) + sum_f [msg.value_f] * >= sum_f [quoteEVMDeliveryPrice(targetChain_f, receiverValue_f, gasLimit_f)] * * The difference between the two sides of the above inequality will be added to `paymentForExtraReceiverValue` of the first forward requested * * Any refunds (from leftover gas) from this forward will be paid to the same refundChain and refundAddress specified for the current delivery. * * @param targetChain in Wormhole Chain ID format * @param targetAddress address to call on targetChain (that implements IWormholeReceiver), in Wormhole bytes32 format * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress` * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param gasLimit gas limit with which to call `targetAddress`. * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress` */ function forwardVaasToEvm( uint16 targetChain, address targetAddress, bytes memory payload, uint256 receiverValue, uint256 gasLimit, VaaKey[] memory vaaKeys ) external payable; /// ------------------------------------------------------------------------------------- \\\ /** * @notice Performs the same function as a `send`, except: * 1) Can only be used during a delivery (i.e. in execution of `receiveWormholeMessages`) * 2) Is paid for (along with any other calls to forward) by (any msg.value passed in) + (refund leftover from current delivery) * 3) Only executes after `receiveWormholeMessages` is completed (and thus does not return a sequence number) * * The refund from the delivery currently in progress will not be sent to the user; it will instead * be paid to the delivery provider to perform the instruction specified here * * Publishes an instruction for the delivery provider at `deliveryProviderAddress` * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain` * with gas limit `gasLimit` and with `msg.value` equal to * receiverValue + (arbitrary amount that is paid for by paymentForExtraReceiverValue of this chain's wei) in targetChain wei. * * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain` * `targetAddress` must implement the IWormholeReceiver interface * * The following equation must be satisfied (sum_f indicates summing over all forwards requested in `receiveWormholeMessages`): * (refund amount from current execution of receiveWormholeMessages) + sum_f [msg.value_f] * >= sum_f [quoteEVMDeliveryPrice(targetChain_f, receiverValue_f, gasLimit_f, deliveryProviderAddress_f) + paymentForExtraReceiverValue_f] * * The difference between the two sides of the above inequality will be added to `paymentForExtraReceiverValue` of the first forward requested * * @param targetChain in Wormhole Chain ID format * @param targetAddress address to call on targetChain (that implements IWormholeReceiver), in Wormhole bytes32 format * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress` * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param paymentForExtraReceiverValue amount (in current chain currency units) to spend on extra receiverValue * (in addition to the `receiverValue` specified) * @param gasLimit gas limit with which to call `targetAddress`. Any units of gas unused will be refunded according to the * `targetChainRefundPerGasUnused` rate quoted by the delivery provider * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format * @param refundAddress The address on `refundChain` to deliver any refund to, in Wormhole bytes32 format * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress` * @param consistencyLevel Consistency level with which to publish the delivery instructions - see * https://book.wormhole.com/wormhole/3_coreLayerContracts.html?highlight=consistency#consistency-levels */ function forwardToEvm( uint16 targetChain, address targetAddress, bytes memory payload, uint256 receiverValue, uint256 paymentForExtraReceiverValue, uint256 gasLimit, uint16 refundChain, address refundAddress, address deliveryProviderAddress, VaaKey[] memory vaaKeys, uint8 consistencyLevel ) external payable; /// ------------------------------------------------------------------------------------- \\\ /** * @notice Performs the same function as a `send`, except: * 1) Can only be used during a delivery (i.e. in execution of `receiveWormholeMessages`) * 2) Is paid for (along with any other calls to forward) by (any msg.value passed in) + (refund leftover from current delivery) * 3) Only executes after `receiveWormholeMessages` is completed (and thus does not return a sequence number) * * The refund from the delivery currently in progress will not be sent to the user; it will instead * be paid to the delivery provider to perform the instruction specified here * * Publishes an instruction for the delivery provider at `deliveryProviderAddress` * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain` * with `msg.value` equal to * receiverValue + (arbitrary amount that is paid for by paymentForExtraReceiverValue of this chain's wei) in targetChain wei. * * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain` * `targetAddress` must implement the IWormholeReceiver interface * * The following equation must be satisfied (sum_f indicates summing over all forwards requested in `receiveWormholeMessages`): * (refund amount from current execution of receiveWormholeMessages) + sum_f [msg.value_f] * >= sum_f [quoteDeliveryPrice(targetChain_f, receiverValue_f, encodedExecutionParameters_f, deliveryProviderAddress_f) + paymentForExtraReceiverValue_f] * * The difference between the two sides of the above inequality will be added to `paymentForExtraReceiverValue` of the first forward requested * * @param targetChain in Wormhole Chain ID format * @param targetAddress address to call on targetChain (that implements IWormholeReceiver), in Wormhole bytes32 format * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress` * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param paymentForExtraReceiverValue amount (in current chain currency units) to spend on extra receiverValue * (in addition to the `receiverValue` specified) * @param encodedExecutionParameters encoded information on how to execute delivery that may impact pricing * e.g. for version EVM_V1, this is a struct that encodes the `gasLimit` with which to call `targetAddress` * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format * @param refundAddress The address on `refundChain` to deliver any refund to, in Wormhole bytes32 format * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress` * @param consistencyLevel Consistency level with which to publish the delivery instructions - see * https://book.wormhole.com/wormhole/3_coreLayerContracts.html?highlight=consistency#consistency-levels */ function forward( uint16 targetChain, bytes32 targetAddress, bytes memory payload, uint256 receiverValue, uint256 paymentForExtraReceiverValue, bytes memory encodedExecutionParameters, uint16 refundChain, bytes32 refundAddress, address deliveryProviderAddress, VaaKey[] memory vaaKeys, uint8 consistencyLevel ) external payable; /// ------------------------------------------------------------------------------------- \\\ /** * @notice Requests a previously published delivery instruction to be redelivered * (e.g. with a different delivery provider) * * This function must be called with `msg.value` equal to * quoteEVMDeliveryPrice(targetChain, newReceiverValue, newGasLimit, newDeliveryProviderAddress) * * @notice *** This will only be able to succeed if the following is true ** * - newGasLimit >= gas limit of the old instruction * - newReceiverValue >= receiver value of the old instruction * - newDeliveryProvider's `targetChainRefundPerGasUnused` >= old relay provider's `targetChainRefundPerGasUnused` * * @param deliveryVaaKey VaaKey identifying the wormhole message containing the * previously published delivery instructions * @param targetChain The target chain that the original delivery targeted. Must match targetChain from original delivery instructions * @param newReceiverValue new msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param newGasLimit gas limit with which to call `targetAddress`. Any units of gas unused will be refunded according to the * `targetChainRefundPerGasUnused` rate quoted by the delivery provider, to the refund chain and address specified in the original request * @param newDeliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider * @return sequence sequence number of published VAA containing redelivery instructions * * @notice *** This will only be able to succeed if the following is true ** * - newGasLimit >= gas limit of the old instruction * - newReceiverValue >= receiver value of the old instruction * - newDeliveryProvider's `targetChainRefundPerGasUnused` >= old relay provider's `targetChainRefundPerGasUnused` */ function resendToEvm( VaaKey memory deliveryVaaKey, uint16 targetChain, uint256 newReceiverValue, uint256 newGasLimit, address newDeliveryProviderAddress ) external payable returns (uint64 sequence); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Requests a previously published delivery instruction to be redelivered * * * This function must be called with `msg.value` equal to * quoteDeliveryPrice(targetChain, newReceiverValue, newEncodedExecutionParameters, newDeliveryProviderAddress) * * @param deliveryVaaKey VaaKey identifying the wormhole message containing the * previously published delivery instructions * @param targetChain The target chain that the original delivery targeted. Must match targetChain from original delivery instructions * @param newReceiverValue new msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param newEncodedExecutionParameters new encoded information on how to execute delivery that may impact pricing * e.g. for version EVM_V1, this is a struct that encodes the `gasLimit` with which to call `targetAddress` * @param newDeliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider * @return sequence sequence number of published VAA containing redelivery instructions * * @notice *** This will only be able to succeed if the following is true ** * - (For EVM_V1) newGasLimit >= gas limit of the old instruction * - newReceiverValue >= receiver value of the old instruction * - (For EVM_V1) newDeliveryProvider's `targetChainRefundPerGasUnused` >= old relay provider's `targetChainRefundPerGasUnused` */ function resend( VaaKey memory deliveryVaaKey, uint16 targetChain, uint256 newReceiverValue, bytes memory newEncodedExecutionParameters, address newDeliveryProviderAddress ) external payable returns (uint64 sequence); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Returns the price to request a relay to chain `targetChain`, using the default delivery provider * * @param targetChain in Wormhole Chain ID format * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param gasLimit gas limit with which to call `targetAddress`. * @return nativePriceQuote Price, in units of current chain currency, that the delivery provider charges to perform the relay * @return targetChainRefundPerGasUnused amount of target chain currency that will be refunded per unit of gas unused, * if a refundAddress is specified */ function quoteEVMDeliveryPrice( uint16 targetChain, uint256 receiverValue, uint256 gasLimit ) external view returns ( uint256 nativePriceQuote, uint256 targetChainRefundPerGasUnused ); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Returns the price to request a relay to chain `targetChain`, using delivery provider `deliveryProviderAddress` * * @param targetChain in Wormhole Chain ID format * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param gasLimit gas limit with which to call `targetAddress`. * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider * @return nativePriceQuote Price, in units of current chain currency, that the delivery provider charges to perform the relay * @return targetChainRefundPerGasUnused amount of target chain currency that will be refunded per unit of gas unused, * if a refundAddress is specified */ function quoteEVMDeliveryPrice( uint16 targetChain, uint256 receiverValue, uint256 gasLimit, address deliveryProviderAddress ) external view returns ( uint256 nativePriceQuote, uint256 targetChainRefundPerGasUnused ); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Returns the price to request a relay to chain `targetChain`, using delivery provider `deliveryProviderAddress` * * @param targetChain in Wormhole Chain ID format * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param encodedExecutionParameters encoded information on how to execute delivery that may impact pricing * e.g. for version EVM_V1, this is a struct that encodes the `gasLimit` with which to call `targetAddress` * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider * @return nativePriceQuote Price, in units of current chain currency, that the delivery provider charges to perform the relay * @return encodedExecutionInfo encoded information on how the delivery will be executed * e.g. for version EVM_V1, this is a struct that encodes the `gasLimit` and `targetChainRefundPerGasUnused` * (which is the amount of target chain currency that will be refunded per unit of gas unused, * if a refundAddress is specified) */ function quoteDeliveryPrice( uint16 targetChain, uint256 receiverValue, bytes memory encodedExecutionParameters, address deliveryProviderAddress ) external view returns ( uint256 nativePriceQuote, bytes memory encodedExecutionInfo ); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Returns the (extra) amount of target chain currency that `targetAddress` * will be called with, if the `paymentForExtraReceiverValue` field is set to `currentChainAmount` * * @param targetChain in Wormhole Chain ID format * @param currentChainAmount The value that `paymentForExtraReceiverValue` will be set to * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider * @return targetChainAmount The amount such that if `targetAddress` will be called with `msg.value` equal to * receiverValue + targetChainAmount */ function quoteNativeForChain( uint16 targetChain, uint256 currentChainAmount, address deliveryProviderAddress ) external view returns (uint256 targetChainAmount); /// ------------------------------------------------------------------------------------- \\\ /** * @notice Returns the address of the current default delivery provider * @return deliveryProvider The address of (the default delivery provider)'s contract on this source * chain. This must be a contract that implements IDeliveryProvider. */ function getDefaultDeliveryProvider() external view returns (address deliveryProvider); } /// ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| \\\ /** * @title IWormholeRelayerDelivery * @notice The interface to execute deliveries. Only relevant for Delivery Providers */ interface IWormholeRelayerDelivery is IWormholeRelayerBase { /// -------------------------------------- ENUMS ---------------------------------------- \\\ /** * @notice Represents the possible statuses of a delivery. */ enum DeliveryStatus { SUCCESS, RECEIVER_FAILURE, FORWARD_REQUEST_FAILURE, FORWARD_REQUEST_SUCCESS } /// ------------------------------------------------------------------------------------- \\\ /** * @notice Represents the possible statuses of a refund after a delivery attempt. */ enum RefundStatus { REFUND_SENT, REFUND_FAIL, CROSS_CHAIN_REFUND_SENT, CROSS_CHAIN_REFUND_FAIL_PROVIDER_NOT_SUPPORTED, CROSS_CHAIN_REFUND_FAIL_NOT_ENOUGH } /// -------------------------------------- EVENT ---------------------------------------- \\\ /** * @custom:member recipientContract - The target contract address * @custom:member sourceChain - The chain which this delivery was requested from (in wormhole * ChainID format) * @custom:member sequence - The wormhole sequence number of the delivery VAA on the source chain * corresponding to this delivery request * @custom:member deliveryVaaHash - The hash of the delivery VAA corresponding to this delivery * request * @custom:member gasUsed - The amount of gas that was used to call your target contract * @custom:member status: * - RECEIVER_FAILURE, if the target contract reverts * - SUCCESS, if the target contract doesn't revert and no forwards were requested * - FORWARD_REQUEST_FAILURE, if the target contract doesn't revert, forwards were requested, * but provided/leftover funds were not sufficient to cover them all * - FORWARD_REQUEST_SUCCESS, if the target contract doesn't revert and all forwards are covered * @custom:member additionalStatusInfo: * - If status is SUCCESS or FORWARD_REQUEST_SUCCESS, then this is empty. * - If status is RECEIVER_FAILURE, this is `RETURNDATA_TRUNCATION_THRESHOLD` bytes of the * return data (i.e. potentially truncated revert reason information). * - If status is FORWARD_REQUEST_FAILURE, this is also the revert data - the reason the forward failed. * This will be either an encoded Cancelled, DeliveryProviderReverted, or DeliveryProviderPaymentFailed error * @custom:member refundStatus - Result of the refund. REFUND_SUCCESS or REFUND_FAIL are for * refunds where targetChain=refundChain; the others are for targetChain!=refundChain, * where a cross chain refund is necessary * @custom:member overridesInfo: * - If not an override: empty bytes array * - Otherwise: An encoded `DeliveryOverride` */ event Delivery( address indexed recipientContract, uint16 indexed sourceChain, uint64 indexed sequence, bytes32 deliveryVaaHash, DeliveryStatus status, uint256 gasUsed, RefundStatus refundStatus, bytes additionalStatusInfo, bytes overridesInfo ); /// --------------------------------- EXTERNAL FUNCTION --------------------------------- \\\ /** * @notice The delivery provider calls `deliver` to relay messages as described by one delivery instruction * * The delivery provider must pass in the specified (by VaaKeys[]) signed wormhole messages (VAAs) from the source chain * as well as the signed wormhole message with the delivery instructions (the delivery VAA) * * The messages will be relayed to the target address (with the specified gas limit and receiver value) iff the following checks are met: * - the delivery VAA has a valid signature * - the delivery VAA's emitter is one of these WormholeRelayer contracts * - the delivery provider passed in at least enough of this chain's currency as msg.value (enough meaning the maximum possible refund) * - the instruction's target chain is this chain * - the relayed signed VAAs match the descriptions in container.messages (the VAA hashes match, or the emitter address, sequence number pair matches, depending on the description given) * * @param encodedVMs - An array of signed wormhole messages (all from the same source chain * transaction) * @param encodedDeliveryVAA - Signed wormhole message from the source chain's WormholeRelayer * contract with payload being the encoded delivery instruction container * @param relayerRefundAddress - The address to which any refunds to the delivery provider * should be sent * @param deliveryOverrides - Optional overrides field which must be either an empty bytes array or * an encoded DeliveryOverride struct */ function deliver( bytes[] memory encodedVMs, bytes memory encodedDeliveryVAA, address payable relayerRefundAddress, bytes memory deliveryOverrides ) external payable; } /// ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| \\\ /** * @title IWormholeRelayer * @notice Interface for the primary Wormhole Relayer which aggregates the functionalities of the Delivery and Send interfaces. */ interface IWormholeRelayer is IWormholeRelayerDelivery, IWormholeRelayerSend {} // Bound chosen by the following formula: `memoryWord * 4 + selectorSize`. // This means that an error identifier plus four fixed size arguments should be available to developers. // In the case of a `require` revert with error message, this should provide 2 memory word's worth of data. uint256 constant RETURNDATA_TRUNCATION_THRESHOLD = 132; /// ------------------------------------------------------------------------------------- \\\ /** * Errors related to conversion and validation of EVM addresses. */ error NotAnEvmAddress(bytes32); /// ------------------------------------------------------------------------------------- \\\ /** * Errors related to unauthorised access or usage. */ error RequesterNotWormholeRelayer(); /// ------------------------------------------------------------------------------------- \\\ /** * Errors for when there are issues with the overrides provided. */ error InvalidOverrideGasLimit(); error InvalidOverrideReceiverValue(); error InvalidOverrideRefundPerGasUnused(); /// ------------------------------------------------------------------------------------- \\\ /** * Errors related to the state and progress of the WormholeRelayer's operations. */ error NoDeliveryInProgress(); error ReentrantDelivery(address msgSender, address lockedBy); /// ------------------------------------------------------------------------------------- \\\ /** * Errors related to funding and refunds. */ error InsufficientRelayerFunds(uint256 msgValue, uint256 minimum); /// ------------------------------------------------------------------------------------- \\\ /** * Errors related to the VAA (signed wormhole message) validation. */ error VaaKeysDoNotMatchVaas(uint8 index); error VaaKeysLengthDoesNotMatchVaasLength(uint256 keys, uint256 vaas); error InvalidEmitter(bytes32 emitter, bytes32 registered, uint16 chainId); /// ------------------------------------------------------------------------------------- \\\ /** * Errors related to payment values and delivery prices. */ error RequestedGasLimitTooLow(); error DeliveryProviderCannotReceivePayment(); error InvalidMsgValue(uint256 msgValue, uint256 totalFee); error DeliveryProviderDoesNotSupportTargetChain(address relayer, uint16 chainId); /// ------------------------------------------------------------------------------------- \\\ /** * Errors for when there are issues with forwarding or delivery. */ error InvalidVaaKeyType(uint8 parsed); error InvalidDeliveryVaa(string reason); error InvalidPayloadId(uint8 parsed, uint8 expected); error InvalidPayloadLength(uint256 received, uint256 expected); error ForwardRequestFromWrongAddress(address msgSender, address deliveryTarget); /// ------------------------------------------------------------------------------------- \\\ /** * Errors related to relaying instructions and target chains. */ error TargetChainIsNotThisChain(uint16 targetChain); error ForwardNotSufficientlyFunded(uint256 amountOfFunds, uint256 amountOfFundsNeeded); /// ------------------------------------------------------------------------------------- \\\
ERC20.sol 365 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/
function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/
function _transfer(address from, address to, uint256 amount) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
// decrementing then incrementing.
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
unchecked {
// Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
// Overflow not possible: amount <= accountBalance <= totalSupply.
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}
}
IERC20.sol 78 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
ERC165.sol 29 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
IERC165.sol 25 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
MerkleProof.sol 227 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.2) (utils/cryptography/MerkleProof.sol)
pragma solidity ^0.8.0;
/**
* @dev These functions deal with verification of Merkle Tree proofs.
*
* The tree and the proofs can be generated using our
* https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
* You will find a quickstart guide in the readme.
*
* WARNING: You should avoid using leaf values that are 64 bytes long prior to
* hashing, or use a hash function other than keccak256 for hashing leaves.
* This is because the concatenation of a sorted pair of internal nodes in
* the merkle tree could be reinterpreted as a leaf value.
* OpenZeppelin's JavaScript library generates merkle trees that are safe
* against this attack out of the box.
*/
library MerkleProof {
/**
* @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
* defined by `root`. For this, a `proof` must be provided, containing
* sibling hashes on the branch from the leaf to the root of the tree. Each
* pair of leaves and each pair of pre-images are assumed to be sorted.
*/
function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
return processProof(proof, leaf) == root;
}
/**
* @dev Calldata version of {verify}
*
* _Available since v4.7._
*/
function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
return processProofCalldata(proof, leaf) == root;
}
/**
* @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
* from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
* hash matches the root of the tree. When processing the proof, the pairs
* of leafs & pre-images are assumed to be sorted.
*
* _Available since v4.4._
*/
function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
/**
* @dev Calldata version of {processProof}
*
* _Available since v4.7._
*/
function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
/**
* @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by
* `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
*
* CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
*
* _Available since v4.7._
*/
function multiProofVerify(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProof(proof, proofFlags, leaves) == root;
}
/**
* @dev Calldata version of {multiProofVerify}
*
* CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
*
* _Available since v4.7._
*/
function multiProofVerifyCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProofCalldata(proof, proofFlags, leaves) == root;
}
/**
* @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
* proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
* leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
* respectively.
*
* CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
* is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
* tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
*
* _Available since v4.7._
*/
function processMultiProof(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
// This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
// consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
// `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
// the merkle tree.
uint256 leavesLen = leaves.length;
uint256 proofLen = proof.length;
uint256 totalHashes = proofFlags.length;
// Check proof validity.
require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof");
// The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
// `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
// At each step, we compute the next hash using two values:
// - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
// get the next hash.
// - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
// `proof` array.
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i]
? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
: proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
require(proofPos == proofLen, "MerkleProof: invalid multiproof");
unchecked {
return hashes[totalHashes - 1];
}
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
/**
* @dev Calldata version of {processMultiProof}.
*
* CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
*
* _Available since v4.7._
*/
function processMultiProofCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
// This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
// consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
// `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
// the merkle tree.
uint256 leavesLen = leaves.length;
uint256 proofLen = proof.length;
uint256 totalHashes = proofFlags.length;
// Check proof validity.
require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof");
// The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
// `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
// At each step, we compute the next hash using two values:
// - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
// get the next hash.
// - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
// `proof` array.
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i]
? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
: proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
require(proofPos == proofLen, "MerkleProof: invalid multiproof");
unchecked {
return hashes[totalHashes - 1];
}
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
}
function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, a)
mstore(0x20, b)
value := keccak256(0x00, 0x40)
}
}
}
IERC20Metadata.sol 28 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
AddressString.sol 45 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
library StringToAddress {
error InvalidAddressString();
function toAddress(string memory addressString) internal pure returns (address) {
bytes memory stringBytes = bytes(addressString);
uint160 addressNumber = 0;
uint8 stringByte;
if (stringBytes.length != 42 || stringBytes[0] != '0' || stringBytes[1] != 'x') revert InvalidAddressString();
for (uint256 i = 2; i < 42; ++i) {
stringByte = uint8(stringBytes[i]);
if ((stringByte >= 97) && (stringByte <= 102)) stringByte -= 87;
else if ((stringByte >= 65) && (stringByte <= 70)) stringByte -= 55;
else if ((stringByte >= 48) && (stringByte <= 57)) stringByte -= 48;
else revert InvalidAddressString();
addressNumber |= uint160(uint256(stringByte) << ((41 - i) << 2));
}
return address(addressNumber);
}
}
library AddressToString {
function toString(address addr) internal pure returns (string memory) {
bytes memory addressBytes = abi.encodePacked(addr);
uint256 length = addressBytes.length;
bytes memory characters = '0123456789abcdef';
bytes memory stringBytes = new bytes(2 + addressBytes.length * 2);
stringBytes[0] = '0';
stringBytes[1] = 'x';
for (uint256 i; i < length; ++i) {
stringBytes[2 + i * 2] = characters[uint8(addressBytes[i] >> 4)];
stringBytes[3 + i * 2] = characters[uint8(addressBytes[i] & 0x0f)];
}
return string(stringBytes);
}
}
ILayerZeroEndpoint.sol 112 lines
// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.5.0;
import "./ILayerZeroUserApplicationConfig.sol";
interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {
// @notice send a LayerZero message to the specified address at a LayerZero endpoint.
// @param _dstChainId - the destination chain identifier
// @param _destination - the address on destination chain (in bytes). address length/format may vary by chains
// @param _payload - a custom bytes payload to send to the destination contract
// @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address
// @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction
// @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination
function send(
uint16 _dstChainId,
bytes calldata _destination,
bytes calldata _payload,
address payable _refundAddress,
address _zroPaymentAddress,
bytes calldata _adapterParams
) external payable;
// @notice used by the messaging library to publish verified payload
// @param _srcChainId - the source chain identifier
// @param _srcAddress - the source contract (as bytes) at the source chain
// @param _dstAddress - the address on destination chain
// @param _nonce - the unbound message ordering nonce
// @param _gasLimit - the gas limit for external contract execution
// @param _payload - verified payload to send to the destination contract
function receivePayload(
uint16 _srcChainId,
bytes calldata _srcAddress,
address _dstAddress,
uint64 _nonce,
uint _gasLimit,
bytes calldata _payload
) external;
// @notice get the inboundNonce of a receiver from a source chain which could be EVM or non-EVM chain
// @param _srcChainId - the source chain identifier
// @param _srcAddress - the source chain contract address
function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);
// @notice get the outboundNonce from this source chain which, consequently, is always an EVM
// @param _srcAddress - the source chain contract address
function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);
// @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery
// @param _dstChainId - the destination chain identifier
// @param _userApplication - the user app address on this EVM chain
// @param _payload - the custom message to send over LayerZero
// @param _payInZRO - if false, user app pays the protocol fee in native token
// @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain
function estimateFees(
uint16 _dstChainId,
address _userApplication,
bytes calldata _payload,
bool _payInZRO,
bytes calldata _adapterParam
) external view returns (uint nativeFee, uint zroFee);
// @notice get this Endpoint's immutable source identifier
function getChainId() external view returns (uint16);
// @notice the interface to retry failed message on this Endpoint destination
// @param _srcChainId - the source chain identifier
// @param _srcAddress - the source chain contract address
// @param _payload - the payload to be retried
function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;
// @notice query if any STORED payload (message blocking) at the endpoint.
// @param _srcChainId - the source chain identifier
// @param _srcAddress - the source chain contract address
function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);
// @notice query if the _libraryAddress is valid for sending msgs.
// @param _userApplication - the user app address on this EVM chain
function getSendLibraryAddress(address _userApplication) external view returns (address);
// @notice query if the _libraryAddress is valid for receiving msgs.
// @param _userApplication - the user app address on this EVM chain
function getReceiveLibraryAddress(address _userApplication) external view returns (address);
// @notice query if the non-reentrancy guard for send() is on
// @return true if the guard is on. false otherwise
function isSendingPayload() external view returns (bool);
// @notice query if the non-reentrancy guard for receive() is on
// @return true if the guard is on. false otherwise
function isReceivingPayload() external view returns (bool);
// @notice get the configuration of the LayerZero messaging library of the specified version
// @param _version - messaging library version
// @param _chainId - the chainId for the pending config change
// @param _userApplication - the contract address of the user application
// @param _configType - type of configuration. every messaging library has its own convention.
function getConfig(
uint16 _version,
uint16 _chainId,
address _userApplication,
uint _configType
) external view returns (bytes memory);
// @notice get the send() LayerZero messaging library version
// @param _userApplication - the contract address of the user application
function getSendVersion(address _userApplication) external view returns (uint16);
// @notice get the lzReceive() LayerZero messaging library version
// @param _userApplication - the contract address of the user application
function getReceiveVersion(address _userApplication) external view returns (uint16);
}
IAxelarGateway.sol 196 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IAxelarGateway {
/**********\
|* Errors *|
\**********/
error NotSelf();
error NotProxy();
error InvalidCodeHash();
error SetupFailed();
error InvalidAuthModule();
error InvalidTokenDeployer();
error InvalidAmount();
error InvalidChainId();
error InvalidCommands();
error TokenDoesNotExist(string symbol);
error TokenAlreadyExists(string symbol);
error TokenDeployFailed(string symbol);
error TokenContractDoesNotExist(address token);
error BurnFailed(string symbol);
error MintFailed(string symbol);
error InvalidSetMintLimitsParams();
error ExceedMintLimit(string symbol);
/**********\
|* Events *|
\**********/
event TokenSent(
address indexed sender,
string destinationChain,
string destinationAddress,
string symbol,
uint256 amount
);
event ContractCall(
address indexed sender,
string destinationChain,
string destinationContractAddress,
bytes32 indexed payloadHash,
bytes payload
);
event ContractCallWithToken(
address indexed sender,
string destinationChain,
string destinationContractAddress,
bytes32 indexed payloadHash,
bytes payload,
string symbol,
uint256 amount
);
event Executed(bytes32 indexed commandId);
event TokenDeployed(string symbol, address tokenAddresses);
event ContractCallApproved(
bytes32 indexed commandId,
string sourceChain,
string sourceAddress,
address indexed contractAddress,
bytes32 indexed payloadHash,
bytes32 sourceTxHash,
uint256 sourceEventIndex
);
event ContractCallApprovedWithMint(
bytes32 indexed commandId,
string sourceChain,
string sourceAddress,
address indexed contractAddress,
bytes32 indexed payloadHash,
string symbol,
uint256 amount,
bytes32 sourceTxHash,
uint256 sourceEventIndex
);
event TokenMintLimitUpdated(string symbol, uint256 limit);
event OperatorshipTransferred(bytes newOperatorsData);
event Upgraded(address indexed implementation);
/********************\
|* Public Functions *|
\********************/
function sendToken(
string calldata destinationChain,
string calldata destinationAddress,
string calldata symbol,
uint256 amount
) external;
function callContract(
string calldata destinationChain,
string calldata contractAddress,
bytes calldata payload
) external;
function callContractWithToken(
string calldata destinationChain,
string calldata contractAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount
) external;
function isContractCallApproved(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
address contractAddress,
bytes32 payloadHash
) external view returns (bool);
function isContractCallAndMintApproved(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
address contractAddress,
bytes32 payloadHash,
string calldata symbol,
uint256 amount
) external view returns (bool);
function validateContractCall(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes32 payloadHash
) external returns (bool);
function validateContractCallAndMint(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes32 payloadHash,
string calldata symbol,
uint256 amount
) external returns (bool);
/***********\
|* Getters *|
\***********/
function authModule() external view returns (address);
function tokenDeployer() external view returns (address);
function tokenMintLimit(string memory symbol) external view returns (uint256);
function tokenMintAmount(string memory symbol) external view returns (uint256);
function allTokensFrozen() external view returns (bool);
function implementation() external view returns (address);
function tokenAddresses(string memory symbol) external view returns (address);
function tokenFrozen(string memory symbol) external view returns (bool);
function isCommandExecuted(bytes32 commandId) external view returns (bool);
function adminEpoch() external view returns (uint256);
function adminThreshold(uint256 epoch) external view returns (uint256);
function admins(uint256 epoch) external view returns (address[] memory);
/*******************\
|* Admin Functions *|
\*******************/
function setTokenMintLimits(string[] calldata symbols, uint256[] calldata limits) external;
function upgrade(
address newImplementation,
bytes32 newImplementationCodeHash,
bytes calldata setupParams
) external;
/**********************\
|* External Functions *|
\**********************/
function setup(bytes calldata params) external;
function execute(bytes calldata input) external;
}
AxelarExecutable.sol 68 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IAxelarGateway } from '../interfaces/IAxelarGateway.sol';
import { IAxelarExecutable } from '../interfaces/IAxelarExecutable.sol';
contract AxelarExecutable is IAxelarExecutable {
IAxelarGateway public immutable gateway;
constructor(address gateway_) {
if (gateway_ == address(0)) revert InvalidAddress();
gateway = IAxelarGateway(gateway_);
}
function execute(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload
) external {
bytes32 payloadHash = keccak256(payload);
if (!gateway.validateContractCall(commandId, sourceChain, sourceAddress, payloadHash))
revert NotApprovedByGateway();
_execute(sourceChain, sourceAddress, payload);
}
function executeWithToken(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload,
string calldata tokenSymbol,
uint256 amount
) external {
bytes32 payloadHash = keccak256(payload);
if (
!gateway.validateContractCallAndMint(
commandId,
sourceChain,
sourceAddress,
payloadHash,
tokenSymbol,
amount
)
) revert NotApprovedByGateway();
_executeWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount);
}
function _execute(
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload
) internal virtual {}
function _executeWithToken(
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload,
string calldata tokenSymbol,
uint256 amount
) internal virtual {}
}
IAxelarExecutable.sol 28 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IAxelarGateway } from './IAxelarGateway.sol';
interface IAxelarExecutable {
error InvalidAddress();
error NotApprovedByGateway();
function gateway() external view returns (IAxelarGateway);
function execute(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload
) external;
function executeWithToken(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload,
string calldata tokenSymbol,
uint256 amount
) external;
}
IAxelarGasService.sol 211 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// This should be owned by the microservice that is paying for gas.
interface IAxelarGasService {
error NothingReceived();
error InvalidAddress();
error NotCollector();
error InvalidAmounts();
event GasPaidForContractCall(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
);
event GasPaidForContractCallWithToken(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
string symbol,
uint256 amount,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
);
event NativeGasPaidForContractCall(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
uint256 gasFeeAmount,
address refundAddress
);
event NativeGasPaidForContractCallWithToken(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
string symbol,
uint256 amount,
uint256 gasFeeAmount,
address refundAddress
);
event GasPaidForExpressCallWithToken(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
string symbol,
uint256 amount,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
);
event NativeGasPaidForExpressCallWithToken(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
string symbol,
uint256 amount,
uint256 gasFeeAmount,
address refundAddress
);
event GasAdded(
bytes32 indexed txHash,
uint256 indexed logIndex,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
);
event NativeGasAdded(bytes32 indexed txHash, uint256 indexed logIndex, uint256 gasFeeAmount, address refundAddress);
event ExpressGasAdded(
bytes32 indexed txHash,
uint256 indexed logIndex,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
);
event NativeExpressGasAdded(
bytes32 indexed txHash,
uint256 indexed logIndex,
uint256 gasFeeAmount,
address refundAddress
);
// This is called on the source chain before calling the gateway to execute a remote contract.
function payGasForContractCall(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external;
// This is called on the source chain before calling the gateway to execute a remote contract.
function payGasForContractCallWithToken(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external;
// This is called on the source chain before calling the gateway to execute a remote contract.
function payNativeGasForContractCall(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address refundAddress
) external payable;
// This is called on the source chain before calling the gateway to execute a remote contract.
function payNativeGasForContractCallWithToken(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount,
address refundAddress
) external payable;
// This is called on the source chain before calling the gateway to execute a remote contract.
function payGasForExpressCallWithToken(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external;
// This is called on the source chain before calling the gateway to execute a remote contract.
function payNativeGasForExpressCallWithToken(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount,
address refundAddress
) external payable;
function addGas(
bytes32 txHash,
uint256 txIndex,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external;
function addNativeGas(
bytes32 txHash,
uint256 logIndex,
address refundAddress
) external payable;
function addExpressGas(
bytes32 txHash,
uint256 txIndex,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external;
function addNativeExpressGas(
bytes32 txHash,
uint256 logIndex,
address refundAddress
) external payable;
function collectFees(
address payable receiver,
address[] calldata tokens,
uint256[] calldata amounts
) external;
function refund(
address payable receiver,
address token,
uint256 amount
) external;
function gasCollector() external returns (address);
}
ILayerZeroUserApplicationConfig.sol 25 lines
// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.5.0;
interface ILayerZeroUserApplicationConfig {
// @notice set the configuration of the LayerZero messaging library of the specified version
// @param _version - messaging library version
// @param _chainId - the chainId for the pending config change
// @param _configType - type of configuration. every messaging library has its own convention.
// @param _config - configuration in the bytes. can encode arbitrary content.
function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external;
// @notice set the send() LayerZero messaging library version to _version
// @param _version - new messaging library version
function setSendVersion(uint16 _version) external;
// @notice set the lzReceive() LayerZero messaging library version to _version
// @param _version - new messaging library version
function setReceiveVersion(uint16 _version) external;
// @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload
// @param _srcChainId - the chainId of the source chain
// @param _srcAddress - the contract address of the source contract at the source chain
function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;
}
Read Contract
ENDPOINT 0x6fad06f5 → address
GAS_SERVICE 0x997f35eb → address
RATIO 0x59e741d2 → uint256
WORMHOLE_RELAYER 0x0f1f9cfc → address
XNF 0x8ab0510d → address
addressThis 0xc8e76982 → string
allowance 0xdd62ed3e → uint256
balanceOf 0x70a08231 → uint256
decimals 0x313ce567 → uint8
estimateGasForLayerZero 0xb7edaaf6 → uint256
estimateGasForWormhole 0x22282f03 → uint256
gateway 0x116191b6 → address
name 0x06fdde03 → string
seenDeliveryVaaHashes 0x180f6cc2 → bool
supportsInterface 0x01ffc9a7 → bool
symbol 0x95d89b41 → string
team 0x85f2aef2 → address
totalSupply 0x18160ddd → uint256
Write Contract 19 functions
These functions modify contract state and require a wallet transaction to execute.
approve 0x095ea7b3
address spender
uint256 amount
returns: bool
bridgeViaAxelar 0xfacea41e
string _destinationChain
address _from
address _to
uint256 _amount
address _feeRefundAddress
bridgeViaLayerZero 0x25c7e35b
uint16 _dstChainId
address _from
address _to
uint256 _amount
address _feeRefundAddress
address _zroPaymentAddress
bytes _adapterParams
bridgeViaWormhole 0xb9631114
uint16 _targetChain
address _from
address _to
uint256 _amount
address _feeRefundAddress
uint256 _gasLimit
burn 0x9dc29fac
address _user
uint256 _amount
burnAndBridgeViaAxelar 0xa0ff97f3
uint256 _amount
string _dstChainId
address _to
address _feeRefundAddress
burnAndBridgeViaLayerZero 0x20767b30
uint256 _amount
uint16 _dstChainId
address _to
address _feeRefundAddress
address _zroPaymentAddress
bytes _adapterParams
burnAndBridgeViaWormhole 0xb2783acb
uint256 _amount
uint16 _targetChain
address _to
address _feeRefundAddress
uint256 _gasLimit
burnXNF 0x6d9bef42
uint256 _amount
decreaseAllowance 0xa457c2d7
address spender
uint256 subtractedValue
returns: bool
execute 0x49160658
bytes32 commandId
string sourceChain
string sourceAddress
bytes payload
executeWithToken 0x1a98b2e0
bytes32 commandId
string sourceChain
string sourceAddress
bytes payload
string tokenSymbol
uint256 amount
increaseAllowance 0x39509351
address spender
uint256 addedValue
returns: bool
lzReceive 0x001d3567
uint16 _srcChainId
bytes _srcAddress
uint64
bytes _payload
onTokenBurned 0x543746b1
address user
uint256 amount
receiveWormholeMessages 0x529dca32
bytes _payload
bytes[]
bytes32 _sourceAddress
uint16 _srcChainId
bytes32 _deliveryHash
setXNFAndRatio 0x380064a8
address _XNF
uint256 _ratio
transfer 0xa9059cbb
address to
uint256 amount
returns: bool
transferFrom 0x23b872dd
address from
address to
uint256 amount
returns: bool
Recent Transactions
No transactions found for this address