From 5be18673add4a866c3ff70440fea747b1eff9c7e Mon Sep 17 00:00:00 2001 From: dRadiant <103012174+dRadiant@users.noreply.github.com> Date: Thu, 19 Sep 2024 15:39:15 -0400 Subject: [PATCH 01/46] Update ERC-5173: Update ERC-5173 Merged by EIP-Bot. --- ERCS/erc-5173.md | 14 +++++++------- assets/erc-5173/nFR_distribution_formula.jpg | Bin 0 -> 21956 bytes assets/erc-5173/nFR_distribution_formula.png | Bin 12607 -> 0 bytes 3 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 assets/erc-5173/nFR_distribution_formula.jpg delete mode 100644 assets/erc-5173/nFR_distribution_formula.png diff --git a/ERCS/erc-5173.md b/ERCS/erc-5173.md index 61eb9e4547..0eb2fcfe42 100644 --- a/ERCS/erc-5173.md +++ b/ERCS/erc-5173.md @@ -317,14 +317,14 @@ Any realized profits (P) when an NFT is sold are distributed among the buyers/ow We define a sliding window mechanism to decide which previous owners will be involved in the profit distribution. Let's imagine the owners as a queue starting from the first hand owner to the current owner. The profit distribution window starts from the previous owner immediately to the current owner and extends towards the first owner, and the size of the windows is fixed. Only previous owners located inside the window will join the profit distribution. -![Future Rewards calculation formula](../assets/eip-5173/nFR_distribution_formula.png?raw=true) +![Future Rewards calculation formula](../assets/eip-5173/nFR_distribution_formula.jpg?raw=true) In this equation: - P is the total profit, the difference between the selling price minus the buying price; -- r is buyer reward ratio of the total P; -- g is the common ratio of successive in the geometric sequence; -- n is the actual number of owners eligible and participating in the future rewards sharing. To calculate n, we have n = min(m, w), where m is the current number of owners for a token, and w is the window size of the profit distribution sliding window algorithm +- _R_ is buyer reward ratio of the total P; +- _g_ is the common ratio of successive in the geometric sequence; +- _n_ is the actual number of owners eligible and participating in the future rewards sharing. To calculate _n_, we have _n_ = min(_m_, _w_), where _m_ is the current number of owners for a token, and _w_ is the window size of the profit distribution sliding window algorithm #### Converting into Code @@ -334,7 +334,7 @@ pragma solidity ^0.8.0; //... /* Assumes usage of a Fixed Point Arithmetic library (prb-math) for both int256 and uint256, and OpenZeppelin Math utils for Math.min. */ -function _calculateFR(uint256 P, uint256 r, uint256 g, uint256 m, uint256 w) pure internal virtual returns(uint256[] memory) { +function _calculateFR(uint256 p, uint256 r, uint256 g, uint256 m, uint256 w) pure internal virtual returns(uint256[] memory) { uint256 n = Math.min(m, w); uint256[] memory FR = new uint256[](n); @@ -344,11 +344,11 @@ function _calculateFR(uint256 P, uint256 r, uint256 g, uint256 m, uint256 w) pur if (successiveRatio != 1e18) { int256 v1 = 1e18 - int256(g).powu(n); int256 v2 = int256(g).powu(i - 1); - int256 v3 = int256(P).mul(int256(r)); + int256 v3 = int256(p).mul(int256(r)); int256 v4 = v3.mul(1e18 - int256(g)); pi = uint256(v4 * v2 / v1); } else { - pi = P.mul(r).div(n); + pi = p.mul(r).div(n); } FR[i - 1] = pi; diff --git a/assets/erc-5173/nFR_distribution_formula.jpg b/assets/erc-5173/nFR_distribution_formula.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3b2b373a759fa3ea33706a8cf197e2b72dcae3fb GIT binary patch literal 21956 zcmeIa1ymi&)-Ku$cNXsM8r*|B!QB!F?j9_-yAwiy;O-iN1b24`?j9fz2zpocKIiQH z{(JT>W4t%+8{_WkUe&YboK;=*b$8jEy`C1H)&a1*w45{m0)YTo$Ob%Zf)?Z?Bwneg zDND<}kb(#R05kwV0t_1f*x9=}tI3Fy>*(r{!>HgR$Mo%**iMC-@g@4C}0 z|5oEaXCj)KxtKsy&LBT(XUN4NWx|Hg*cQLj^uOrWztcj$Xm?jfSBQ?vFWOl{O#(uj zLTGx6KhdxMM4LD||I&|!=m^=_y8XJ=ukfpOC}#GW>X0J>Ic8kwZkpka9UdHVeQOFayW|Ilvw;0azgv2fzlf13XV(0SN#G z8v54`0}TTU0|N_(1P=!ZsE9}iNa(0wFghwa8U_|VHU=ghCK@^pF%BL90TB@q7@LHQ zgpdrMkcjYCCLkDCSU6ZX6nJH;tjpm|^cXb>d;g#m)b06p~pL=d>4 zpnpAY{|c~h&@k{ID2NdI|H1!F;b{p#frcajLxUlA>f8FiQvFT*jlkas{NINF&M+At z>lFFx0A{=A9nb^LW>wVyC}^4!&JlpaVgmrF#JIR>jVPOO(fFjUI8WM$~vM)GXiY%2<9t5Ojnr2w;_uFReQ>fl_zDnSoSxKBm?(WILwOP*z=a|Efa4iI_ zt$;c7gJk4weY9<%6_iY+6z=1S1|st>KjmqYL>rBPOL8j41x!`3>~1b^-$F#UZ*RSz zDynsC1na5F7$@OHHA4!d8;H)nR_`Rdiec3|=gdcW0yqzXw!RtU7z$G;I8x*uzg<2Q zg>?QDJbUlD1=Vt2YOG*oOTJYZi=l`m&QNuLpNoDjbV%^pY-sjfx@+}c)W^j)VRS4W zmFzu;G#=yN&(Y$TOg@a4=)a9lAHwB6>E>k}xPC+$wJErDDjRLW5KC;@;h&eD{mQ^u zt1F9t6dv$?xY9*`wZF6FlsQbG+2=GN$+1pS(|o>OdPv6MeNLfU_)n4OZF2&?DVwZI zW_W@9H9>fRsr~k3Jc+ZN#an64HzB?SWO$JzXQi{JF2NdKzR#Jh@zdIHJ&=LHua+RzygE z{5M@BpFAU=Lf1{nWOid$^f%UjI|9kIAjnlu+*T~hD>td`3G6Tbv&{ePEdHbzk`55B z<-54#L!&=CT$XKEDM`)MR!)62_-HcuNo=BO=Fb05+W!L*`om?cy{o^`?usbW50Ly) zL!{qIy}G^VpRz!a)+$>3xLcG~-_8{Q_i`6bSZLsi0w?U;z*u1~wQIhX;#X)W{K+ja`L;yMv0FlS>*hJw|{`nnAEo zPe5dzgW2cvV$SGSVdYJ`JMCCmVHm6P?|=clu)!8n?izfHxM3*KG;vWj3?rxeHB3Re zvHL-shWVl}3cKKhyWQ?pQlV#00A+_yK;YTs8WoSf&Vg>3@jI1dHMwGe!i&$V(yzOg#BGRbpVebgweiU}c1Qi5g|PSf){IkHWoB*GEfGgv zTR#V`;T8LKUtSsv5)SQMQ&yzqS^7w2+sWPkOo#)If~9Bym-OuHDAT3VZLE1- zV9(%R*O3@v__4QkVH_{IF=Wb6x7qnXl3V?0UmB3F6I;(Jt8yR})| z`>*nwBMl{yow?0SU2N0~r^%)t5E#fZ)6o`xNIi&!FS^%_p+A;&bVc<1goE*zlB_B` zqupeoFoO4dcD&TWxUKia6i57H4;BilO8Q21?n(1hq3>1jY)vhW<+HJaxnMU0Jzca4 zlV!eynlj&+Z_C%mxz|3#Pr%7zNA-1BaMDZXW6iN%ga1#WxzAP#nxs6=AB8yjNJ26r z3SKE=c%g$^W9K%rp$G=34skO|rEp*!nc6t{^`AG;7?4vN(j+UKS2+lGj2E8vJvZ$!kf`L@uq&?eaz(Hub%)cTR%podF6aBgg? zTo204yE!%CLv8F^C*Q_9sP0uVQSlDFTSqF4=0swPW;DzMSZHyR0ORerc!h9+vz&90 z49rfnv%rA73fK7van2q&W<-H6t^gcUsAB}xL4;8-TMvDY{l=7GMYJRKEA3VTiEx>C zU|k$AA3drJ#t4KLXXZ`BrsEGbUF9eyCbK1x*^n@em*G!vBJ#-=jLsM+sI}~Q$8TF> zpvOLA@^Q?|+RtdgyL+GCGB59KVY4g@V$TSd)i~q2*t{<+IwLOB{>CsX_W zPHiEcz`ajJyH;Ux?s6keJZx=nVX@7@(B4!3zLE6o7Fk|IlRS?ey>GFtDo#_$pUfX$ zNb6N3S{MDC`l!28CXvz2+aO^w@-rBp*H6H~3lImJW^wBi066<_S$~fIG5cvT9N<9P zCM$BeybfquyjbhjlFT@1S3vjhC8V*8GQQC9?(Rrf-ssoynvz>4<_$3wO_hotxT*W0 zw4%Mtek2m|TN^VpF>EOBr|H|uqac59c%i9@RxQJ&4eJu8sXjB)0e8<}{0$vy+%XJK z@$kD@Nd`V_U-Gdv&yCq2+*cf<@(6mqg%!P~TSW!6Tl_K3pEP{^ep1aguS_8qzin2c z3fIA6UkodD#)Tzh{1TuOdOa=bW?q1&mC@zI4ic&vPF;d#>Jpaq_>L+MI`=_cNLc!$ z^7Y2y=1l}*S-;T;!xLa(2SpPkO5qsnpG`N*<1TvBWefj)5ve9v@(Ez+u7`D{LODB6 zZJo?Ls+4$m2x}Fh!);yF<{aAfG#F=kzvCiQX^}E=(HuD0@PNuMXikr~Q__yt9g^;t zQg))WbVZH0HXo+t{^O7Ew-g9oD%b5#s_?G(%?`X6Lj1I-FJ65Ljny@^51r`a0`MI~gU3#mV zxv2qx)~MuwV(c}uHj`B;Lx5?bvH3BkaUG#xTCvf<{LoT+M?(Xq=t6^FB)_iWL1A(E zWp$3&Qhpoae0f17i?tFbcFJWKqJWH?iJn`dgtjWmuDq9C1@fzkkx1Rt8cq|l4e}=+vFy4my z1Wx23N*CV!(Aux1Y>YoIasTSbJAUh{AxqyPASn3%L<8zy8cLAC00|MAcq9CggNZPH{`PCR3}ZJLh+7 zoSowa2Itmx{bQs6CjuEMq^L$1E1t}JYY7ol_H*+q7;R6^NW=r&(Ptj})CXiJ9{Tg^ zE=XqFwdHR;*GX|Imo!qmHTFh3+ZxB0B4=TuD1VfUXDs3KBn8DTJ!66q8%dI*RxBYl zlRYB!j8mC|bGiw;(4~xYIVA8@85hnxDGL^uA(IgrpRb7fq4pO2eZv#b<0p`5D{R#N zm{64Jbbqe!yq;7ge2wvog0dU(ryavS&a&FV6yr&gAv_1&JLQ%1T4j zRA@mFj(ng}z^0Oa#@K41B431dxcCHYOmFOlKj*jTb9Z9Ri!`>QEqtZxiE}-@(z(B^ z7eq~l!n@hSMl*sOn!{&uvYo#X7|zWnglMJeVDoq)aA&lV|xl+lS^r8aj=x+2gH&~o-fM8_^hjQq9> zT-08Cho@yFw^N*Pewxg~_!k|#x1R@|fL?uNq+o3&Q4{#8T;&I0q){ZCPoK1=h%N<3 z5m+cMEP^Iev5uHrZRs4;Inck5;H_Eci`)ymrH^93l14SVekk&Gn<|O!U+HhGVy!%*Ye~`-b;fo>lG~2Z(|ORM z3jYqD+=;!gQvu3OpqC={$G`nv^Ejj&aKK2CH$L^!^_vyf)=97xik;HO?p`1P|yDP5nvV5E4!pPa}6|77YXIMG3rYN1h zd?6`n+>%`G;&1OXT&m!voXX#j2D7ajh;Hi0-EZjCCmVN8d{>ty*h!%juFdHy1@|-8 zO6MUF??I1z%7R&yBQ#|p+HPT6<~ZVIA1tC<(Hi&rzT@+3x75)-d6@p0E~?pu4l8|FXU?G6$(!dm*Xi7;RM3ZL{dWw)@E0-bjlm-J0XH#Q z`r@yeMDGn_>Ld$^3Yn^eq+#_JK<`p?BaVBO?ax6-eU*vOJBrM^RuyUm(D6l-YD3bVX&u+Fr69ttXtDFBhSMAdO+@@rom{PiF9KV zJg58uij0{AzuJc$)ch-rM0$Afy(zx@mP87)vkcIpm{9EL7L`CwluFfcTfyVY_iqyq z*P!{+S;#LH9w|QS@$;3T5M~ziotOwQt`gkH^@bl0jw>i+C&dbAQ_sY>VK>fGK3_(p z+@dPKdjfD+hNP)iqT}_kpHVf4YibOqu5-=^DpG9`CKIcV3R=d%$(8T~>E-H`ZZq)~ z%BU89gJ3^YVmcp8?kleW!u-<`TxQG7syIr`VYHTnv?xttw?-JLdY{f2R(~N6+^f z(WgYcKI`I1*oozZ@iE_z?+HM1ud~~hcd9B*Pe-6VOVkCQ!fBa7L=k-DL+kJjg0_)wso^hK>{5}s*;w)2&7JKn#@wQ`SHF4L#%*`SbK<8AiT5WhUlZEBhY`x5(o+fX?a zp|Zd*ec-Vli}IvFEn&rokIVH|c9ZejaayT|#>hp1`PT0s8RGz()1;cICNFlQ(Ntn* zt+|A(Hh0Xpk@3Zp?8DINwtdF0{8<9o1Gm-dREd+iikz@t80-R+lLO4G6 z>q`bV)chTn87tjnTxE?Ps&cBP5;NVD^|GZ03o=NP`IbA;j#cpyR8N4Lll~}jYah2s ztN>yt{uW(UO271bRYPxl^J+eH&KCo<&rDF}itRRIS~P(?+_W*j=Pt3gvGfnJGxWKY zImzGQ+G5wba0;nXj%d(+n@SsxX%bdH^}HIuxhU-0ry>dAbW>XMF-5jKB!#8>1mW%IDR zC*;jPbN9@W(IL;!hWc%qcl#3{`1=J>6j_#Q!at}n26Rm5l6kCUMti1CoIxEbPPz62zc4PEB#nG# zwC_hvU+06l72+*Dezw%^XK`aUNpep*Y+8ZuFzzybdY{(sL^u$ZW}J?WO{KG~Ozd5E z8<4uxg_o-PiR8INWkn9cU`sRu3g2FKEBHg$z$K{PP)L7}V)io6maXc5Rb&5w6LA;+~89nxy~B-A4$r_7>sI%N@TGIFO&Nl;n6$g;@E*2NwPVt&5~ zFLjd4tIEu?wrbDWUze#|+ZcMXEmlGkZ9>)RTkzZaBy2u+pLOH|six%fdZmG;a8jKN<4@kCHC1IoW29*K-Tn6QbYm~HJ;zvjKi+6 zP7N2@2K}MLV!k0BtBlXVFAi~eUZXvQSh_7Z=s*~cTGtGb?31{gvb zdem`tF*Q<*J%O6N*8nEwDb0%#Yna%1Gj$3?gH2q4Yq2R=NDBFOEaIi5}^v;s?haGkOh?2|7 zqSmlanRi^lILWI>46extW$GCY-$P52berN#bE*kV12FsN!3^7yi3V zg8SEB-WOZ^P|wGbVWKO?>7;B}9*VEBX@o^IMi{iQE7QBGbADI>RuqZJuUbN~&jbd- zk{AZQBcN!vYJJsmcPwBpsrz~b{rmlKl|y)0-lu$Cl^N6}GW$vpKG?6c{S7+86QKF_ zm=xo&^yh*Q)r02uY7d#)vOS}-xGU|k&JD7|yf3cyqYQCdk2y*l25?MwGLMk%Qs8m&35XRL%f%h7B%zY9o=x~xMs{wsi|Z0XESKM& z_L?sM_t5)i)BBcYE78NLZQsM@re>FCiOXE_d*$f8935PqT=?!JkYx{I&8@H5u}nHz ztR$xA`=3^CwX{$R)JyVDgb%ZH&I`v#h((0vCOqaPRkB0gdsx(KEwxGMoNV?;$ZqV% zatwEI98kVc7{=M{O?>TzZ{rYrC_Bn}2?v!OBpYEhmNvQu4Sp%NsLa#xK_G|Ry1362_!1Z)KuX(qUum+lV#eMy*5A;h*e@AbtyiZ>u zjc0br6t=|aU81*>MzWTYf0`)U4k<`#2ODN$cH8kcC4?cuYf2GM5oBt>xm=cB=$u`IOK54taI7Z?L;NNde*G|oiR9$oO&}v*E;$Gxuw-0)wwAG)T;`Y=^l6?C@S5-HVMbt^I=@p(_yk1pw zafIgbmomp3XJzFpmsoWeXhYm$1>cy)UF{5fV`+!ri!$cI(f& z_nRN{SetbUdMTZ-xuz8Je1@_?5kc_#ZQAm9mRCv`_w(F(!xwbMgO>*zYY+epA!|k~ zV2G^;8VU{s@$dZIR}zE)P_T=sf{mRLI?n>gb86Ti79y3&jgIqwnubIuo`9iTW(5T( zn}NAJ8EiC_uN6-~(bN&G%M*~$dn?{bcP>_4TeoAQl@3QN91=a%5gK=Q^loqK-g!)OFG5x%Qw` zq-a)ITYisABVhg}GO7U+>i8i8^$9@kty>VBZ5CJkv1uN~!MK%{|C;nF){UAte4BTt z(<(DIC(fK!VhJ_{qCH;w_PjT;O9*Ss@^zdKLIa!epuNuIekKVz{WWnw?GB2pdgAJDo>tb77cI0{KdHvNNX z*=(tb&!()>+bmqdKF8(|*L~4R!(>l)Ul=%puX0p5aZ{}1LNA)N6sWb5Q zZ&IgM>%r6LaeE&Yc^A6#C+e33_`iNcput8%+mJytLV(H&H`6+zjgr^}P(o>EbD=4} zV!TdLG_`tDpOUy|d!Pa%1gheFlccH@fj8W(9M~lnmJ~@B751JGCJ7W*3zg z+7Rv5?qa^@h=r zv%%mdY}<1jM+PU{4H>EN9W_zT9g_wXqp%f-VVb$>vdYTbY}=(=kVT{3$|$v{(lF3D z;|YLSLmdj;^ZM`XyEv$0SAX7_7_{%|2xyx_T#)`ldbQJ`$#hH*P;Br1ANE@q7zWcM zj5fQmE=q|q^}cwN@Q8xGmDu!*GBtswY-!(WyN;WH9J-dAZRy?eF(MaFD!^jMkp@Hr) z#+B`l#GvK>6lM_QQxHBR}GN z37@M$U~(1f_57&N1F;3U4QgTb)Vcy2c81CTLR=j-gBWyzA@0Zwc1FYGqRwu#L8JlP z+GUJ*1Xm&oKgUful=#u)7j%b@>mR=2%hOaDoxkkdYzyl3hL8M#j&n@Pv>>Ei?eYIQ z8w$(}m*RJX5Y^YbffEGn7T3V;&a)fx9W<1q)H#vkjD6QYKHAq9a4z+dkr#vMy=&{tVOzuOl}?^P1li75-Xikop=+KApO241Y`H}FS! z_Cq7gdojrNXF}=<87j)J_cB zKZ;ucF@3eWpy4LCN>B3R32=asa8%gOSi0SEl19nLBJIIdV!=YE!?yY=(G)9e)NL;Gi}Rj z`{Xl?m~5b(RdJy_Q{n+E4PQ#^dpLSai zXLtFUZm23fmwH7$F8Zo>QnAouTjRm|qI&+;!Z*Q4``)AI3DBxIofs|+J?ZwrwX(=y z8A`_>Qpu7Zq87LDcBj|gt5DoyPdR)7gq>_OOIr)GWX2nqGly^qs~=asknXK{?Hrt? zswj6}BG5))ymE(?+$Tg!!D6@LlXRrY!Qq4Wh49jp-lio2qWWg z5Oedq)~7@Gk_BUKfc?3L9vm*^nF_)&OOx!BzhiFK`YisJTA~?Q{;Gt6cB|zPlc3ih zN}bw+u8^gLMY@>H!xQln9;Bf3eUM>3<;~>r3P7RLm-mqYA-qqk^hFCb)Wz|QzU6qOuoX%}riXq7!MJbvnZJ{NE6{z$OCYzh0j?*S zJ+;kgAoZ|*!y*o*ZcegqG%Ur8%^vWJOhVsrN3*{)a=(aUCG*(H%-q{e_aHnSXgrWQ z8~dS@tLV%*R}M)&sT;Vw+G==+1h2#M;%@e^P8ZpOn3m;F>gLkn0+tM`Rfgv;TQ>chJB*ON5U9ex5sAciXI?{kv?3->Wi#V{B?Mv|rtcZX7^=`+ z@SXvdsxFZ8xdwHeZ@^W;ZXBN^Oxg^9nlD{-`9vwTl{UI!x*@rosrTgUo2$2MMVb@l zu_DZ%n$r|t)Y-`K&r>=Gav8qZfgbWXbXp6f7y{#Kl$%${7w|08Vg2x;6CWa(NgTA# z$*qiV9jp32nbTyqfKBZUhSD3;+mj7sSp(GIbU>Vy+Fl%}x@>9}MVUIj*7$JF^m2od z2rvCrzd>qJ?X(#epBqc(>VH}2mS4`!Ec^s?UbjaKPk`K98>I6{;5Xj*4a-boeJrFp zikp_$#uPo!V=3l4sTs;1h4;55>$hDJH-7IIWT zfr>*plR#kuf!RO^7#+X_(r?*_f#apf|BDR${~;HJ<^zlJLA@ZJfCocIfOBQI5@Wgk zDg28(f`Bd2zYzTe8{C2Ndvgf|fV2NX=dajMaOD1fCHpV=2mk=fXCnGv>iv}hxa-dn z5DK^p;n(-I0l#sf0a4LEi~lzo2IUVH44)c0LbWssmIN_5Gy*0dR5OHP^oRIAP}t-E z`F~*j-sAW~zCwohEJNz`7eVFkj_EIu`J4SW0)Hd$Hv<2s5cp4AQhzzEg8xgW)!#Lk zz!1X(+iV55Fq&hlzqb;FonGA*bd{rK9r?0|odAD9z0c5vQ!F){CPkld&`l z3ILg5tCd!P?u5FS)}ULyKT^#-GB2Y0SDlAD`8V(&7?N5LFky+|g);kOJ^-44^CqQi zXk7TVH786{uiTYj!zI*Gl172RH{$3p;uBdoc8Ayg(CgQ-Mle)d=U^n z6g>OBuk@I@F@3u}!rA+tc6NDa@=L8NcNG=heorI+m~g0l&8jbNH#1SnRa_Tvl&a)n zj*H%R#JoFcAK8Mq-;yTamk?lNQkrcm<`3ja;bmj3O=_%OY+S>U;$DTq7Mw4&l{I*3 z4w(2Z$daHpH&>M`nce%65uxU;7?^(z3m^|cr1CE$@_?6;!%J2SWh^h*MyhhkJ2f9b zsrLAkn0==%^V->2DkI1!(=3-~zj{aY>^Zdf7@J&Typk07O-`kgw54b~FZbZ*SUoBM zC_uZIb-_J4`yER#a1d?bA~OHw8XQILT_LomBZ1ZaWqqX zI8kWvSZ$UF{D{|w6UX%49Qo2SI0D!#B#2j&i~cy&XKDZ@XE-Q-i(ftT$_&c$duZdJ zSl3jTJ>x$56fgnvJbEi52YLG#An6Z)c(?CPq@gLUga}>};+OXn8Hqkm5j#IQc$m*W ziL}v;Ktw8lyG5$~KH`qlxn+6FS+|r^wL{SX)n`m>U;5J;8(?NKhz{yfBYCW@_HWl( zGgX!*bXdqm6rE_!qelvKIMFl!6ZBFJn_?0P83{y(U<~1NB8-HELOE*cV zpt;T;9=CAR8sFXyT6~3h)fr|BfX;kdQ&pp3iTaJQz7l8RJhuU_l;jFt<^w97f%Y}Y zTTuIQfGBhjH*U0a8woIA6SFyIx|2dfFPKcvk+umFD2fIJ;$eEzO!!if@e>?jU8<(@ znG9uYiuCihtS;wCO!Ye?WlgLMCWN5$Xqimd0QML2t0+Wikv~amlE12frA{o9C8haE znSE8^8eq8S+WIbRH^ra^5z2!<EFxbII7_@4$(?RxZofH z;BAHOy)Z)h=3O)k(W&RacP{B7N!LaDd}c9uNk9QuVzFKv+m-cds^%>ojbX`m(`I8G=aS`)u?iVycy)?nZXiHk%__ z`tD+n+W!2yv0%<%1ejTQ4I=xRNlz*AT9pK@PA7}=4}fSRLyjaI+v{~%s(MY{&Q*Tu z@}7NUl6tD+jXic$0CbPvC(IgblH058?`c%XNR5I|;h2m4jW7k%w$(UlycW8Ex#lb) zLYyFwF=SaSd%$ojr-^aWN(-^6Y#-vndjAB7D`dwI2$gF7g!qa)-2G!M_1_=163JEI z{Dn+vxXmJ{!ITUN7hcp!N7yHyvFGzVvXo7H;3YvuP+c3;Ue*Tg*;Cr0l|lxp!Wu|Eu5N=^Z6BuHUyOF(!fzINo`MVk47d5x%}y)bMK>w0J)1~5y` zZQ6waSZ0{)D8ONhwqb-n0p%1JhB3BNi!T&!sH`nf675$$U!tHSSf6FH$xpfm@M2%U zE*$}Nx|qpkHGZ!f-nZL>d!wl`F;zjuP`^S>J#2q>wP2 znd@A4IufUeM->~eELh7XVLhRzJkT(Sc55zm|eY~$5HGsJgF<)La$c|>K2ur z3hc2xFsO1#h=j3)!>k)3xt{1o`)se^Xc@LwLKO$~CDAi2<3tb!{YQejptAdkSCUGB z5z@&Ru{YgaZ2oBex7>XsLC{c!E!Q0Yg6OI|oN2Rdw0WeYY%yDFT`K-CH|hf@9!I)u zAUxvuR!J)()Or>`+BO-$tv0|!b_HDa6D}MyEKkosPF@#F-(L%YS3p!5@&`jN zpo_tXQ|fsP4*Om_8-vWu3DKuG4scYYP_SU(#jdoN3msy776m(^5M+sy~}`2EF2#?&)L%+@xI<;t>O`qPB8yu^QxL%U1d=t zKwZp0NJ&hz9$PD&e$|Ji@Gc&el6^US+Xmm;h^tQ^Rlwj0IIXQIUTEAVcaM}bD4ANY z5-o9Hy5q@X)V4_iKhIPmTS7F2Itwt53>AQeqFYyBw*Y((9y&I<730-%Lq3x1y&<&D zqZfUR7dya)?ei%|==0WA{UzvauNhW6!$X!lwh6HV2W>bCEOznrq#OTI=Djm=z7-wv z9XspW9+Pa!P9`~8t{piaXM97%x>VxjDA9Z1*jGBzqzB#<%$QArlharrJq>XXN;TiAI`QeMdQ6=XFe|=I7YvKMygUik^Se1vIdC~c5Z`1rMM4S8+GuJcpB@XnjjMwuX`|K1nf}R>4?g4lAguJ$y-_b3dR7wpGp7qJR!szcM$VHh)fDj9EGI zqUw1{Y>-wLBLel+0iiJR?2j%K#iIyvuzw&BSz6vEH8JfSOJ^Qta-;NPV>b$;0y(do z!#bC(7k1$XX#yf#&=5K4Q7|L-*;jcY@osy-SCy8?upVUS79JhaRf1m{N709>9mUHa z`q?dvZ5Pg}GzG_1b!&2|K!pSuc34rn(vU;MVn4(Is%-+%S8_Nve```LK!=d;0iH!_ zhbI$(<{EnI%u*#sJOl|FYhkZ_KH+ns?02`Hmrx+mB+3m|N&E4L`DI5V&)8Me&)l+UF zs1P;M2>Igstb%mlM1ZK&cM92{7@(uHK{6}A$S;HuXIEK=dKN9)#w*NYws7TEGPEa0 z&wQxSe(siF{pPt!tPB)mSvKk>pB#lK>ViLffMExD;n+v@9&mA&aIXKUS8gtq>8a>f~|>vXF_vy>9J@pPPvG@AEF&kp6tfsbzZo) z_Wf{@mP*@aM%ksCDt|06nY2I6f3hBLj?-kBK0iiiOC>I-3uGx{PEQ$u%r8Z4jP%m5 z>O}`~pm>m2HIA9qi5m}slMT|LD8EPBo>HATIjaDVE8mBix#zuV>&2RcfrOX-KM@04 z<%6+jurfFRN*b)Kc^QAapdv>Q@Ph;MTor*Gtm(gJ!>JK`gKhh$V=O#jWGvkUR#AkW z)F(i8W9x(qR(S~xPsFJ8L5hZjP)yGbpmbtT%1g#kSTG0X(!zb8x$9nE(l+w9tsxIruI&JOl&8l@0&-*~FU=hckr6n?QOSZKM?kyyp=q+92T#aYrVBgExQsvufQI!BN2KDK zMl%?|xPX&p7olq5yl($}IIJk%#~f&Rm&?GMXAl#v8X_qh02fr%ja6)* zp>lvB+1b&B_=?(U-in*H8Zqr49|X__T^iI$=G6n5z6c%l^|Rw%_SEK8 cSJHd>$rmUQiOWz3_LJ~>yib60%hTfj0#h|SA^-pY literal 0 HcmV?d00001 diff --git a/assets/erc-5173/nFR_distribution_formula.png b/assets/erc-5173/nFR_distribution_formula.png deleted file mode 100644 index b4f42acd4aad6213b3be4470c088098bf64e62be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12607 zcmeHuWn5HU^e!S2(%lTrATfYJx0E0uHGss>NOuq2C5_ZAHet$>09(9wH$jVav%re}#mE8~|JwqN4(T zQ{OKEH<0c*zLJqZDjT3$1HLGmK;=wdzC?NiT%#i)-y=Y}e=7p~B86BWq1;^~Au$7= zNJ#fH@BQ~Q6Z!8`)a1*A#lMn!|Z*N2BY41dwEQRTzFO_K}Z5>Q#pK)?=a?y)C zq@|@5axgX(c=cTRpXR_fVR~~XCp!TM#MRZ6)Acc@t%Dhao1dQ_!o>sO;o$%zI2_$= zoM3JoHjWH`I{Dkra}!4+2MaqV3tJo7+kRn&w$4t%^z^ri{{8u5r;~;0f0}F@{}~oA zK*;SA2sbAeKKJ<$gm%^dwxKh>$plTRifelIirduloh-uaS>U z&3ZOFwYH*Y@aFm-=W5QgBL#};Ta{HzLG<@9WW|sP-uj|2A`(!p2Vad%zL5Xt2JJlz zM&w5UE-3$rbfBoACV$>5twUi1p5C@pCjW%{w+C83Cgx0@&mB>=KbZb`{MNTO)BC^v z*tzc|wldjx6?6WpR}FRR{+<5Y76xG$g;<>Si#pE#>dfRZ2i=@BP9Fsv|7$HH;(w;#|KSw)S>T=S_}u7R9+mr0v#mAXTbrhwi-(& z4>T>2j)~UqA&Q>ce9*##Sw<?FfNa4 zn>nIIuTKR?D=a6#ClH^rzU%>w$GtVcjxbjq z-)*=QF25VW`9p;=R1~uO`hx+%2o9YZB9PCeef@JVp~-~jPGf{ojBw2}p<2p-Sr!?cX7{&Uvyy?8iZLgEGo@qz;k15E&tHLUlW)=rERVGn(OZT}x zi_UHUY?2ed{Hg?hMdjGf{Qxq9$@!T!=xl2CT0{OpVGgp9-Us)UcVY5iYIld5^YP~J z;_@beJ@@5A%{P4u-J;j_d&BY&V#~1-*5g^9n*}t{Q*phhFB#=JwPmMQJ3g~2oaalt zvtA?BR`uI;mNGxf{2EyAcE2i9CJ&!_L)A+mBJp5?3aZ5A>my#wb*8&ev2*p$z5 zVP9C%-LhNuN97SIS)qq<;)9-@lun|-)SggvD$2jS4!$i^bkjuWY%!3iva2|M zLao7kmzIf?{dqxiyswSC6>X3FP-yt0hjB_Wi2lpvJgyJ;7yM%DQscsFYqI)LfHg(> zt+z=b^h|0WgYIzVhZ)BG z7>_RJTEs|`Oj;psi2-VkgQp7W_K;2B4omz3sry@qNlxU4c%Old!x1H=L554P%y9m6 z_}zBw5B4RLUC9kp63}6H1ooePcoZe?@!=1Tv*qM?Vy;?W7`cSYtoKQ}R2%)zR}0~f z2lyDU@2%XkKkr`e`feh+K`r@dNs1zYcw-q@zxO3N`aW0A>Bime(EZ(`_EktAOgFe) zt{_7yemBsB>@qiAG5j}mH=JZJ+E=y7peJ2`+v{enAcLe>vz${=Xs@HpT9T4y$p0B& z`5fum$iNc0cYdBh!T!n?X&J`yarl#SY73V0uCY>`_;R+@Y1KP_Y0!&en&bGs?-Pc> z(HrN)GL77x`Xl-sL^RC(p`{`3hH6KI5tO98t{Y!|iFSi%@GBd;Ep&}u5!yl@Vp*rZa87QyuKBiO97!uhMHfctrAP?&%}Z{cZ`loA8=d z8j=Qwj2s#$T8=k{rn;=)I#IV!bI}@^;+;1SX2=|zOGw<(VghNTPOm4gMg`^N?J~(@ zia0b6YUel1izd-mD8^DNVJh`)JOpY0ZgWw&_E962c$d z7t_Gmbh?n8mswhfmekg;iISi?H)KgD|?F{lAXc+9DT3%Ml!CS&|nMkuuoSqlBg54I2eMT zfXl%k^l)o+@x9V2gzRI7^^XNEMDcWUNz0!We-)B0?ixYKe(_G*Ny;26)LCdz3U0g8 z-Myv}GC+Xbo3xS&tF@g?-=_B3ZDmXE#3tg)EqcnakQf7{tw7I4cMw`H%z32an4%(3 zl!xilI<{-1b2dk1N%vxac5M}xA8b>;3jPt`MeNzhF^daoP#$%^?teU(Yk)>&C&qs& zJHEJkvD=QTn$FHlE#Uz!hCU{~b6QXv&MY{e*RO@&DlrM*0YVPhuE zYyayOd4A(Cu9OvYIjf|{03(u4DY(gKXjAXZA%j}#?V!j7J2l!B=4_YvJoAxPjPS9n zC9Sl_=7M-58g}ce8*ys^4EP=c1A7Y9yS)g+ZuOr$DdJ@dY@ySpSnRVMsV>H7SYim`Ix!@W{FMnm<^GIWhW9zn z1OZ8Bc-Fqd*+;bAZ$8%t84E))pqD?+zuCg$qi4?sTs0Ja%i=O$?vzvwytsawVEv;= z-QqX(tn7d%hDosJL^c#h6a#Lh8CuRl=wq0Y;kaMUqoB_jKYo|fC_|9zxz0Z8NmV{+ zCon)yr29EG3}zz|PH6QSW9yad-=<~;5w*cz7$>e`nc;4jg$xIjYeVvkz8@4aB)u#N zogval?^HGqT;($-v7>Prb@aObuH&GK(w1na`3C-K+Z;sHnrhqhW!0E+U1F;1t$X<; z+TO=~q2c@(YPUH*i(zH(55zwnq!k0JmLMu?LpC#SF7N0UYH5yUcjaKEf}J6CL!E4i zY+z$9Aun(0~_*c^ENZNX^K6y;K#tw^zUN z-g4M#>k^(oipegySPB`6Wp9X8Ok}7EC4V?zhEIqqsuEn$E&yfXXjfxFvh@^*J33VVe?9=u)$^P=;Tcn>F;@%bPO8_dlCw=*gaD#BIG;#E{W-t zzqXMR2~{7oct%HF`f;IKBy||;T_2A{)5}t}<`V61zba&`R5t{|JYe5^CmJ4LQYP{C zO1wj8*Cdo2E3z%`2N9blHD^v#2lB-7`n* z6Ir{YO_0XoSWMvLIECnf4auej36&*{NK>*t{7iOYE_KSoqF@J!6ZUv#?N{1~p6F~5bCz^Mi+%>AZs?J)Y|D^ELs=yd8cX&S2C#1n zdRpgssyM01f`jE$HWcHrpk?buDo=;CL|%oyq%B!YJ@s523K$1tseo*4O~Fi`cdowH z!F8L+zFp3ir1aMSC$J1u-J)ISn{53!_fEmmp!4;+b>i}M@7`w$?y|h+jLTUf5nyf9 zf}%I6p8DK(fY3T}Oh{)FDAOahS^o5ETS4il!sCw-7WIz0&Zu}^CFo(8KI&bTjFhWla? zJb?t~<-pC^mCfoX%j$Oyg=w977wgu^yeg8{blUI$Nw#~b&#YfOp7-`_(kp{BO8+QCT;%cC!^m zGW9q4slwM;c2&PPE~-~Arc@P^8YrYsr+2@AF-!1>X7Gr{V2SOa^|CUFtx|6|`X1fG zV5hoQg57X=3oDk;QrH58Bx74v*%^=hyY}%(&@PL#+cohSwJvPFEGHQ*c13NGvQ`=C zv?p7@+>xbU>)Ao~7asIpxdrE`y8$qf`&2Su2eJ0@k=GKa_vI(yD{OM(dnWT&l@3%I%ct|)3N(jR zK<2^9+Mk6kt-F@0zLf5{EmutTTsM@EM0e~BwRBIFkZJ~X5h7URXjGM2t`kRtnm5(0 zBGhOq=}SD42u^9!#1Gfti|eljLlx5eG)2I6-$o7hQ=Mj5CQw4aE)!qGCZw7SEK-x?0x^sisMs^Ecmhj zZt6Du1=bsKt0M%neDP!6FCJqrkuk-6VIPy)y;{fMJpkZ{AFFPE6|eKay~}F<=W)yi z*|UL@qiAYJLsZN1i9L|_A-)`ApMe1DRq=a8R&7tn)}tmpXKLpB*HHg`*s+6f$QK;_ zRzwpvp(_O}XY1gZ$I%bXc;`~9w7!GcCU4KW{tL<^;d8qQg4a)Dew($1Vv!wpK1yGW zPi7D;D1BQgMJUfs(htj<;^HRp9BzA<5z*ekk3D!tV;F#uxf?o^$EaPWW0QEovYryO z#cVfSY;VZMCv&zZChK`vTwHIIH>VFABzp+;>z8$yfCWx$7nWm`44achEwEp(>_;$M zcpWVCZx9alb_?JTwug64&4b$06DUC~j{q-22 z|1KeLLF4!vB?~U|Q@WXR=P$1>-6U}M=6sKH>>^rtU7@VFgsLQ7BINrJd9UcclT?>2 ztA+gP!lT$00=$-2zVWV5taa$Ja*JJq=*4E$R5)QT`D5P+6UMgZXA?OTU-jS4Z^kSH z5%@2&vNOVhB))u2`^C^$I}5KbP=Cv%J`#4gAlsCMj-wqPWd}}Gzjo+k+NW^p7%yfI zI7i!Ps}6o3NMy$RvV{$0Y$j!&N(#?JWXA{0(j!Hxn-G1ukt}^JG#utY2npoL%yl8$ zKJm~ve#|5y`s5hE@=J~s%Nzxi@YL4CN-j&%3G3RKS81>ywQmfj7t%hR^pxJBJL9ZF zoHr75o`C#_Dqm1_MYu`D2S#@ppQWnc!QV{DuZNpR2l=G=`z#LYqdkr>RqM^#qr)hh z;3#cog_|)d&2ifF7z)8+r)EDI2Wy*lHBWE$+&i1gQ=Ja@4Rvc|Lk{qUTUW!4P8qtY z_y}y@g47b7=o|SK^re1{GMtb`td0o9>7RzHi1xNR>qWz_7}8Z-)@giNd3t}9ax9Qr z;ALEf4f5|D@ZipL&wG{%h!XsdsDmEj3OKN zyXrjD4`_wfhLq$e6)*8Ko*bM@pY_R{zedanL8Y{M=Zp2?dDo&CVo{xQBS+&shsqXn zg^NF*W7TLYT0FZ~!VG=g+obia%(==kQpG|}(=HIF!@5h@A<>3MK@w>*>_MLAHk01j_-O6wJ&b4hCOW&h;8&B0(v+gtu+9}TL!_$%j z9MAc#y@pn^6`;>`UX1^|ih0I4$j+Gz`~K9r2b2-^8obfgQ}Rji;2q69xJ9+Vw8YiJ zcQjE031>&-&31wrqbK3|3!hjX-(+8o`suIs4s`hG|GHwQbkNpA_EPNH0(l)HpixH7 z@1Ij#X~*t_*>h-L4VU*lo{XzoAxM%gvF$ZRHz$8hRz2g7Bk8Lje|m@r-6~Qq4h|C- zM_f{LFZfkGv-F;~?8+{w->j6c6g#|lAUy6r$mK|8u$ERW^(I*TNijFNLbeaWhB~R) z-k8ARunz>PH95uFz0ypwEN^@^Q`AR4yS&e_P~AI6U-RCi>^ZGQ&tO^`o74w~%#@?B z`%YN+o$TMqn$7^`E6wzZ`?;(eV{lyl>xLj%IJurb<`CXfj-}66M$@MT?|@k~uRP1JzT~g2PMcinYfIbj_7+!@hzak~~v2ss!fPs4)v=6XjlFzc*>Y z+pS@yk0uE5mwGbG1>$bqWe*2dO02t*DVtsJ*#oQ^;NQj3sz=Pw6Taf_nRLImDZ%a{ zz~vJNIYLmk65awqY?ir`Urv-z6T3REm)@=DnRcD$>H*;c3N0|NQ=8_iqjBh=V*|MrJVP;rX?vkaLZwm7 z%xjqbAQ~~`1A1jalehB-gada#sHg`2YMy&9Ye9d6s`Y_XmYAZzTJB_016)?n zx~O59_FB2-rwhh%g!4zT?9O$njq_!=XBu~bV`skseCf6G5A{w>eQ)(!I?zJ$;+CYm z*s7g%;(4lmhr{2BJwUEjL!AhDdnM>N|Dec;papm9`eFx??y>%H08Ni6DB>%5PgfM> z)br2X@YpIfR22m+&fqH%5P-D}feph6<-ZAINr!T~=jtlo?G#{DAJZc+>nFc~%U?`z zZGNq@#KP{blW0(wm<-WMUbMki`-q2$hpxyD?RPQRe3dnt+_KjV$}q+3p7d84_CA^6 z<)Bk-0u2hkxW(|kD5m0>E+PT2Zx~W<QJa+0PEvgZZ2!tY1MKH( zFi_jiSUTpHfo&yMGB>&&+^h|Nh7~@;Twwd` zey|dK^dK20k~ry(%hARwoZ;erF?Y6_G5f2mSOG(nKS8qOQM?+W_l&*msm91t%P}Xc zj}VD3$rX{8z8J;4A_1FxagZmCkqRYMcZ)n4AXb{tx=Y$&IBdJ8@8aOL6e|-a2^Z$V z;go_3poOppzjA_hC>4ukjDN26GS zVZ&q2hlb$XO-u#t10v>$j*e9Kr1pltRVb(sa)^aUwC^o7O_n6Km6SxT=65pdBZ~d43&Ac~|E02;hz2o;qI`srujstR2X1{oLJ*m@sgxkj%uARvKeTQF{`Gl-tGe z7F+i6k?!92f1Khyj3>b@ZL9%UAv~}9lsO3%q0LcG(ItPzko3_F0+otA!&^2hX7@;^ z)<)M;GydviR&>T}Zx#WTrU3gFq`7Eo_r(Y)Uy{M4?@75!>`^@V$~0Vb5$o+qP9W1p z(JLI7#@%-Q&gN9%uSm#$~Tw33dg)0h?!d?aOr=j^^5LR&+DV(@Hj;o^Urr zAa|EcO-}|HhDhN{RW?MR38u|4$kHg7!q5fTW1&O4_>pwWMayNDdea%z!e51JgoQr@0!GShVu>V)_=%n;q#;hf(eGF+w_?39C0xDW z$Biewjstgn*swyoJ7SfWk0OR&xY*zGM^9kfo z`cMb=jndj?Q-9iCb{^LF;^e++5AwshQ4A3om2CE zlZqa+vSdv9H4m^Q;nSH+js_SqL;~0TtoCPpC-KZPm0aYZX{w=pv0fFUub9(W{{%cB z9%r-+vj$uRvlqnF!}%M|*NZ+MS?iq*OPK(aiZwGMy5NxgP z$Zfr_*Y=&nTQUm0FcRLiinlK8`7=0kVRt?VFjJKd;RMvjz?^p3?D6eOvCu~$7y?{cnlyLhA3t^Jl1qvf%y|cJJ-9Xi$jyv9=i0g6WpFT15qh(v;KT*gRMVbNOL?|oWKH3kRhn(hs zuFOjwE`WNpgHm~I6|dop!5{--7?i?(#g16}uk%w#2Wojs?>H60=OI12+l6s#{{1M? zbVenC{dhEt3Ouk_TdBWW(YY`Nz~ z)IbYA@)R5hb{7KW;#HPlZ%{q@JKg;ufGV%gN>9eCEywc@n}GVGrs4^JO z%AGd99?e^hD>91h8WZZrVJhe`0_%lBz2OHyKyx)nA&zbM!@C2lbO$>73=Sh9gJw?P z?jWTZS{#LXXSS@tM+`(UZYAKsU9V!*N%`3E23>IoJKtA6HPijcDaj92Jq7};th(?* zD8nInxpaO_^@9yD%^7 zJFjW{f&97(%=zNSm(_H^h>}V77Sv?2lKf(g(l@i^9{cklpnTnEWy6W&bn3TIr<({! z6L=dCeev}m&)p7w_Q4{9?gICj)%T?M*z4TrOX9WVeC(4rv#zjf`{U->3#<& za0zXHUaT{jJ&0^W%WS!96NFr;g)UG?`a<}#&e?K5 zXcAyA>e(Am+}(F2u)^%@zu_-OlQPQla4%+Xv1E8TwD$3mmQ^T!aOh=Sdp2*_sHk_j z`RH&V0+RnZ*L^;Sl*H$JB;ysiGJ%9!SL8L~O$CG>b|IILdev{n3Qo^*i;9EvYJ(S- zPp#Uur0Vj-b-0b)CQOpm&~t_b=+zRhmKrOwQk1mdTmq z*)Dk-1H+3y90V-k$&=$p^wI$7S)$wbSuOufzy`(nwLWOb#MYan;iYf*pRfihS>7e1 zFn%{j24ez5nXdgp7>mm&Asf2Czbx7HExUN=zbF()%Gjni4|V>TzXwp5>}2Wv`p>!5 zI`Nnu5+o7mUH9mDZY7SLc9gGu32?y4VxM`|8+cWdwLIG%y1SWKXsxR z%)1e=vi#NG>BFnwqG5TJVhW!GJ20#4X}S8#`^8&}F{0^26hwLEAw_!y1X ze)E+@)MVXB>!YI#DKd_Ls!S^yz#|Of8GtduwBi~JRMLC>^Gs*zoVTU|jaF$&n7JEB zr=C{ko1s6%TC<+0%q#r~W1SC*3XJQrqq??h2vi|E>kApZg-XV{K!$v&BJH^RWWPTK z9EpVwsZ-W3@z}*MZ6CGB@IIEa?(Bb)kT|_As2~uJML9O|+Y|cB5S(%C8#k^*rk9U9 zT-!?!K80}4d^^nRD8)5g)+T&@q3b&HV|xeR=es}+{=lLEK)<6seq)RdSLg8Goc`j7 zA8tX;^qmiI>zVH2t`h28*m(J)+V$*q4a^v=y^DO7=2!NG*XA>8|8xmWqjR+ zY9^m!fvS@)F~-0=>XD3}p*?+C`GoW$L$ zq8hcqsvn-+2cZDmpvnt|b7w{<6E0s4bfM-g=GC)liv5e3fyEHTU1o*;YtH14I+rSw zwK@VXn+te;`jVKU5x~=M7#?Z0f9EMdDI)A4=G60Y3vKQy+2>r~tH%;_G-Epe}|El*E*It8;0rJ@@&OD*) z03+ZkxG_5Hs5HchM2R}wvbZ;$flRVQxgljYR!5%9#kglXGXO_hg<`>IucfjR6Ccx% z6UNU!=X-yDifw>ApP8CH1suHW)QjKd5tdz1*cSNk^9srLU1};dmdQZ!5@%8((Q{eZ z!;p4dQ6ZZnp_LuN^@s;wrmpwem+;F7jUR64UDfGip{I@qff!*wwn=_@=HP$l;iIV4 z?hMC;^eHdpA8HdjNCbsJwst?hSFU7c@Czdl(~|hI*hw6HYV4aqJ8aDto6L4?Nykn3 z4udYY9q(~CD4h9PpAKxtcV%RaA+OIKJhgFQ0CUXh*Nx&@BC2(p9pG&dc~lCc`~c(; ztlUUM^;51STN&(=JB9KDaeYEdTC%}nfY+M%OJteJrM&%(yVstjUoSPAtp~-Z&{zb8 zWvac}DRR%1E%g~14DCihUTu%BnI`)jx=xcxlrw_5UiJ}sS3NxNhvD13bH9GoF1l1k?#(s#0;2C@lt9FwO?vA~j!^LqjyJ1gq zHkXLq6E@!JtD5rJMGoFGiL6|L6?p%ue3f4l!6U_ASKa;z$XE}nv1&XfvgP@P48u}Z z$}8_*hXJ>WN^~b@d;Kt5IwuPE>_?uKevj4Ud&^uWWEYaR^> zYip~vU+i*OpElw)KMkzL<1}e~p9F~^7<^}+TJAay!DhDZ(k^6{iwwCl7{4&vhU`8Y6ly*fZ9iIe3&Q zO7E%EkTLUnZ(b>scti-%{ z7Ls*^A5aGkteLhVu1k)WJ4hCqFq)OnrJnGD84V8HJ2;*_d^upucQS zy$rR~nB~R#=8WA3IG&0ymN@^|H%Xb;#ct=CDHoduni`pN^5b=KYkqdH1jku z7`f-Y>8S&kns5Y@LRu2VlznN z364B_@RXyKK6Lmiw|lLc?k;5|j9LLUH7jSW2WKom_qRoog?)<^CTa;Kxc}hZe`$mL@X{_Q4veWW0wt zq^N4B?&$(W56c6+-=3yAIs*TJkWeRN972c(=0L^eDYhPPu&!imlJkLNH&75a@f7}e zeE%<7Mo`Ffk0YSkDyb7pq=Pb_lY%MP)kyN?k(0KYkwLrqdi)XzBJdLOnz zS`}ubegzHkp<^@4`iH%cmjEVHj>2R3hp{xbU^*(5=}!;;ZDybb*q9UdIQ`$Tnj-<~QJ-Y1|91d62RM54KU4Jo(-iIAAeGvsD?EF3 Sd4Buv2y#-2&&wnX{Qnm-RqvPp From 33003678d3efb46030da469cccb81fa5c3c522ca Mon Sep 17 00:00:00 2001 From: djdabs <87738563+djdabs@users.noreply.github.com> Date: Mon, 23 Sep 2024 16:32:44 -0700 Subject: [PATCH 02/46] Update ERC-5791: update to v2 Merged by EIP-Bot. --- ERCS/erc-5791.md | 166 ++++++++++++++++++++++++++++------------------- 1 file changed, 101 insertions(+), 65 deletions(-) diff --git a/ERCS/erc-5791.md b/ERCS/erc-5791.md index 34e06f58fb..14d38362c2 100644 --- a/ERCS/erc-5791.md +++ b/ERCS/erc-5791.md @@ -2,7 +2,7 @@ eip: 5791 title: Physical Backed Tokens description: Minimal interface for linking ownership of ERC-721 NFTs to a physical chip -author: 2pmflow (@2pmflow), locationtba (@locationtba), Cameron Robertson (@ccamrobertson), cygaar (@cygaar), Brian Weick (@bweick) +author: 2pmflow (@2pmflow), locationtba (@locationtba), Cameron Robertson (@ccamrobertson), cygaar (@cygaar), Brian Weick (@bweick), vectorized (@vectorized), djdabs (@djdabs) discussions-to: https://ethereum-magicians.org/t/physical-backed-tokens/11350 status: Draft type: Standards Track @@ -29,12 +29,12 @@ The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL ### Requirements -This approach requires that the physical item must have a chip attached to it that fulfills the following requirements: +This approach requires that the physical item must have a chip attached to it that should be secure and signal authenticity: -- The chip can securely generate and store an ECDSA secp256k1 asymmetric key pair; +- The chip can securely generate and store an asymmetric key pair; - The chip can sign messages using the private key of the previously-generated asymmetric key pair; - The chip exposes the public key; and -- The private key cannot be extracted +- The private key cannot be extracted or duplicated by design The approach also requires that the contract uses an account-bound implementation of [ERC-721](./eip-721.md) (where all [ERC-721](./eip-721.md) functions that transfer must throw, e.g. the "read only NFT registry" implementation referenced in [ERC-721](./eip-721.md)). This ensures that ownership of the physical item is required to initiate transfers and manage ownership of the NFT, through a new function introduced in this interface described below. @@ -42,9 +42,9 @@ The approach also requires that the contract uses an account-bound implementatio Each NFT is conceptually linked to a physical chip. -When the NFT is minted, it must also emit an event that includes the corresponding chip address (20-byte address derived from the chip's public key). This lets downstream indexers know which chip addresses are mapped to which tokens for the NFT collection. The NFT cannot be minted without its token id being linked to a specific chip. +When the chipId is paired to a tokenId, an event will be emitted. This lets downstream indexers know which chip addresses are mapped to which tokens for the NFT collection. The NFT cannot be minted without its token id being linked to a specific chip. -The interface includes a function called `transferTokenWithChip` that transfers the NFT to the function caller if a valid signature signed by the chip is passed in. A valid signature must follow the schemes set forth in [ERC-191](./eip-191.md) and [EIP-2](./eip-2.md) (s-value restrictions), where the data to sign consists of the target recipient address (the function caller) and a recent blockhash (the level of recency is up to the implementation). +The interface includes a function called `transferToken` that transfers the NFT to the function caller if a valid signature signed by the chip is passed in. A valid signature must follow the schemes set forth in [ERC-191](./eip-191.md) and [EIP-2](./eip-2.md) (s-value restrictions), where the data to sign consists of the target recipient address (the function caller), the chip address, a block timestamp, and any extra params used for additional custom logic in the implementation. The interface also includes other functions that let anyone validate whether the chip in the physical item is backing an existing NFT in the collection. @@ -53,73 +53,80 @@ The interface also includes other functions that let anyone validate whether the ```solidity interface IERC5791 { - /// @notice Returns the token id for a given chip address. - /// @dev Throws if there is no existing token for the chip in the collection. - /// @param chipAddress The address for the chip embedded in the physical item (computed from the chip's public key). - /// @return The token id for the passed in chip address. - function tokenIdFor(address chipAddress) external view returns (uint256); - - /// @notice Returns true if the chip for the specified token id is the signer of the signature of the payload. - /// @dev Throws if tokenId does not exist in the collection. - /// @param tokenId The token id. - /// @param payload Arbitrary data that is signed by the chip to produce the signature param. - /// @param signature Chip's signature of the passed-in payload. - /// @return Whether the signature of the payload was signed by the chip linked to the token id. - function isChipSignatureForToken(uint256 tokenId, bytes calldata payload, bytes calldata signature) + /// @dev Returns the ERC-721 `tokenId` for a given chip address. + /// Reverts if `chipId` has not been paired to a `tokenId`. + /// For minimalism, this will NOT revert if the `tokenId` does not exist. + /// If there is a need to check for token existence, external contracts can + /// call `ERC721.ownerOf(uint256 tokenId)` and check if it passes or reverts. + /// @param chipId The address for the chip embedded in the physical item + /// (computed from the chip's public key). + function tokenIdFor(address chipId) external view returns (uint256 tokenId); + + /// @dev Returns true if `signature` is signed by the chip assigned to `tokenId`, else false. + /// Reverts if `tokenId` has not been paired to a chip. + /// For minimalism, this will NOT revert if the `tokenId` does not exist. + /// If there is a need to check for token existence, external contracts can + /// call `ERC721.ownerOf(uint256 tokenId)` and check if it passes or reverts. + /// @param tokenId ERC-721 `tokenId`. + /// @param data Arbitrary bytes string that is signed by the chip to produce `signature`. + /// @param signature EIP-191 signature by the chip to check. + function isChipSignatureForToken(uint256 tokenId, bytes calldata data, bytes calldata signature) external view returns (bool); - /// @notice Transfers the token into the message sender's wallet. - /// @param signatureFromChip An EIP-191 signature of (msgSender, blockhash), where blockhash is the block hash for blockNumberUsedInSig. - /// @param blockNumberUsedInSig The block number linked to the blockhash signed in signatureFromChip. Should be a recent block number. - /// @param useSafeTransferFrom Whether EIP-721's safeTransferFrom should be used in the implementation, instead of transferFrom. - /// - /// @dev The implementation should check that block number be reasonably recent to avoid replay attacks of stale signatures. - /// The implementation should also verify that the address signed in the signature matches msgSender. - /// If the address recovered from the signature matches a chip address that's bound to an existing token, the token should be transferred to msgSender. - /// If there is no existing token linked to the chip, the function should error. - function transferTokenWithChip( - bytes calldata signatureFromChip, - uint256 blockNumberUsedInSig, - bool useSafeTransferFrom - ) external; - - /// @notice Calls transferTokenWithChip as defined above, with useSafeTransferFrom set to false. - function transferTokenWithChip(bytes calldata signatureFromChip, uint256 blockNumberUsedInSig) external; - - /// @notice Emitted when a token is minted - event PBTMint(uint256 indexed tokenId, address indexed chipAddress); - - /// @notice Emitted when a token is mapped to a different chip. - /// Chip replacements may be useful in certain scenarios (e.g. chip defect). - event PBTChipRemapping(uint256 indexed tokenId, address indexed oldChipAddress, address indexed newChipAddress); + /// @dev Transfers the token into the address. + /// Returns the `tokenId` transferred. + /// @param to The recipient. Dynamic to allow easier transfers to vaults. + /// @param chipId Chip ID (address) of chip being transferred. + /// @param chipSignature EIP-191 signature by the chip to authorize the transfer. + /// @param signatureTimestamp Timestamp used in `chipSignature`. + /// @param useSafeTransferFrom Whether ERC-721's `safeTransferFrom` should be used, + /// instead of `transferFrom`. + /// @param extras Additional data that can be used for additional logic/context + /// when the PBT is transferred. + function transferToken( + address to, + address chipId, + bytes calldata chipSignature, + uint256 signatureTimestamp, + bool useSafeTransferFrom, + bytes calldata extras + ) external returns (uint256 tokenId); + + /// @dev Emitted when `chipId` is paired to `tokenId`. + /// `tokenId` may not necessarily exist during assignment. + /// Indexers can combine this event with the {ERC721.Transfer} event to + /// infer which tokens exists and are paired with a chip ID. + event ChipSet(uint256 indexed tokenId, address indexed chipId); } ``` To aid recognition that an [ERC-721](./eip-721.md) token implements physical binding via this EIP: upon calling [ERC-165](./eip-165.md)’s `function supportsInterface(bytes4 interfaceID) external view returns (bool)` with `interfaceID=0x4901df9f`, a contract implementing this EIP must return true. -The mint interface is up to the implementation. The minted NFT's owner should be the owner of the physical chip (this authentication could be implemented using the signature scheme defined for `transferTokenWithChip`). +The mint interface is up to the implementation. The minted NFT's owner should be the owner of the physical chip (this authentication could be implemented using the signature scheme defined for `transferToken`). ## Rationale This solution's intent is to be the simplest possible path towards linking physical items to digital NFTs without a centralized authority. -The interface includes a `transferTokenWithChip` function that's opinionated with respect to the signature scheme, in order to enable a downstream aggregator-like product that supports transfers of any NFTs that implement this EIP in the future. +The interface includes a `transferToken` function that's opinionated with respect to the signature scheme, in order to enable a downstream aggregator-like product that supports transfers of any NFTs that implement this EIP in the future. + +The chip address is included in `transferToken` to allow signature verification by a smart contract. This ensures that chips in physically backed tokens are not strictly tied to implementing secp256k1 signatures, but instead may use a variety of signature schemes such as P256 or BabyJubJub. ### Out of Scope The following are some peripheral problems that are intentionally not within the scope of this EIP: -- trusting that a specific NFT collection's chip addresses actually map to physical chips embedded in items, instead of arbitrary EOAs -- ensuring that the chip does not deterioriate or get damaged +- trusting that a specific NFT collection's chip addresses actually map to physical chips embedded in items, instead of arbitrary EOAs that purport to be chips +- ensuring that the chip does not deteriorate or get damaged - ensuring that the chip stays attached to the physical item - etc. Work is being done on these challenges in parallel. -Mapping token ids to chip addresses is also out of scope. This can be done in multiple ways, e.g. by having the contract owner preset this mapping pre-mint, or by having a `(tokenId, chipAddress)` tuple passed into a mint function that's pre-signed by an address trusted by the contract, or by doing a lookup in a trusted registry, or by assigning token ids at mint time first come first served, etc. +Mapping token ids to chip addresses is also out of scope. This can be done in multiple ways, e.g. by having the contract owner preset this mapping pre-mint, or by having a `(tokenId, chipId)` tuple passed into a mint function that's pre-signed by an address trusted by the contract, or by doing a lookup in a trusted registry, or by assigning token ids at mint time first come first served, etc. Additionally, it's possible for the owner of the physical item to transfer the NFT to a wallet owned by somebody else (by sending a chip signature to that other person for use). We still consider the NFT physical backed, as ownership management is tied to the physical item. This can be interpreted as the item's owner temporarily lending the item to somebody else, since (1) the item's owner must be involved for this to happen as the one signing with the chip, and (2) the item's owner can reclaim ownership of the NFT at any time. @@ -129,34 +136,63 @@ This proposal is backward compatible with [ERC-721](./eip-721.md) on an API leve ## Reference Implementation -The following is a snippet on how to recover a chip address from a signature. +The following is a snippet on how to validate a chip signature in a transfer event. ```solidity import '@openzeppelin/contracts/utils/cryptography/ECDSA.sol'; -function getChipAddressFromChipSignature( - bytes calldata signatureFromChip, - uint256 blockNumberUsedInSig -) internal returns (TokenData memory) { - if (block.number <= blockNumberUsedInSig) { - revert InvalidBlockNumber(); - } - unchecked { - if (block.number - blockNumberUsedInSig > getMaxBlockhashValidWindow()) { - revert BlockNumberTooOld(); +/// @dev Transfers the `tokenId` assigned to `chipId` to `to`. +function transferToken( + address to, + address chipId, + bytes memory chipSignature, + uint256 signatureTimestamp, + bool useSafeTransfer, + bytes memory extras +) public virtual returns (uint256 tokenId) { + tokenId = tokenIdFor(chipId); + _validateSigAndUpdateNonce(to, chipId, chipSignature, signatureTimestamp, extras); + if (useSafeTransfer) { + _safeTransfer(ownerOf(tokenId), to, tokenId, ""); + } else { + _transfer(ownerOf(tokenId), to, tokenId); + } +} + +/// @dev Validates the `chipSignature` and update the nonce for the future signature of `chipId`. +function _validateSigAndUpdateNonce( + address to, + address chipId, + bytes memory chipSignature, + uint256 signatureTimestamp, + bytes memory extras +) internal virtual { + bytes32 hash = _getSignatureHash(signatureTimestamp, chipId, to, extras); + if (!SignatureCheckerLib.isValidSignatureNow(chipId, hash, chipSignature)) { + revert InvalidSignature(); } - } - bytes32 blockHash = blockhash(blockNumberUsedInSig); - bytes32 signedHash = keccak256(abi.encodePacked(_msgSender(), blockHash)) - .toEthSignedMessageHash(); - address chipAddr = signedHash.recover(signatureFromChip); + chipNonce[chipId] = bytes32(uint256(hash) ^ uint256(blockhash(block.number - 1))); +} + +/// @dev Returns the digest to be signed by the `chipId`. +function _getSignatureHash(uint256 signatureTimestamp, address chipId, address to, bytes memory extras) + internal + virtual + returns (bytes32) +{ + if (signatureTimestamp > block.timestamp) revert SignatureTimestampInFuture(); + if (signatureTimestamp + maxDurationWindow < block.timestamp) revert SignatureTimestampTooOld(); + bytes32 hash = keccak256( + abi.encode(address(this), block.chainid, chipNonce[chipId], to, signatureTimestamp, keccak256(extras)) + ); + return ECDSA.toEthSignedMessageHash(hash); } ``` ## Security Considerations -The [ERC-191](./eip-191.md) signature passed to `transferTokenWithChip` requires the function caller's address in its signed data so that the signature cannot be used in a replay attack. It also requires a recent blockhash so that a malicious chip owner cannot pre-generate signatures to use after a short time window (e.g. after the owner of the physical item changes). +The [ERC-191](./eip-191.md) signature passed to `transferToken` requires the function caller's address in its signed data so that the signature cannot be used in a replay attack. It also requires a recent block timestamp so that a malicious chip owner cannot pre-generate signatures to use after a short time window (e.g. after the owner of the physical item changes). It's recommended to use a non-deterministic `chipNonce` when generating signatures. Additionally, the level of trust that one has for whether the token is physically-backed is dependent on the security of the physical chip, which is out of scope for this EIP as mentioned above. From 9689c5ac08dc54df3b6529a59ffb1693ff2dff66 Mon Sep 17 00:00:00 2001 From: Lanyin Z <106770708+lanyinzly@users.noreply.github.com> Date: Tue, 24 Sep 2024 11:12:23 -0400 Subject: [PATCH 03/46] Update ERC-7527: Update erc-7527.md Merged by EIP-Bot. --- ERCS/erc-7527.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/ERCS/erc-7527.md b/ERCS/erc-7527.md index 042dcbce31..0f53f4d4ef 100644 --- a/ERCS/erc-7527.md +++ b/ERCS/erc-7527.md @@ -143,6 +143,14 @@ interface IERC7527Agency { */ function getStrategy() external view returns (address app, Asset memory asset, bytes memory attributeData); + /** + * @dev Returns the premium and fee of wrapping. + * @param data The data to encode to calculate the premium and fee of wrapping. + * @return premium The premium of wrapping. + * @return fee The fee of wrapping. + */ + function getWrapOracle(bytes memory data) external view returns (uint256 premium, uint256 fee); + /** * @dev Returns the premium and fee of unwrapping. * @param data The data to encode to calculate the premium and fee of unwrapping. @@ -152,12 +160,10 @@ interface IERC7527Agency { function getUnwrapOracle(bytes memory data) external view returns (uint256 premium, uint256 fee); /** - * @dev Returns the premium and fee of wrapping. - * @param data The data to encode to calculate the premium and fee of wrapping. - * @return premium The premium of wrapping. - * @return fee The fee of wrapping. + * @dev OPTIONAL - This method can be used to improve usability and clarity of Agency, but interfaces and other contracts MUST NOT expect these values to be present. + * @return the description of the agency, such as how `getWrapOracle()` and `getUnwrapOracle()` are calculated. */ - function getWrapOracle(bytes memory data) external view returns (uint256 premium, uint256 fee); + function description() public view returns (string); } ``` @@ -216,6 +222,8 @@ Token ID can be specified in `data` parameter of `mint` function. ### Factory Interface +OPTIONAL - This interface can be used to deploy App and Agency, but interfaces and other contracts MUST NOT expect this interface to be present. + If a factory is needed to deploy bounded App and Agency, the factory SHALL implement the following interface: ``` From cf8bff877b00d56cec0c60007a25bae0937d0d03 Mon Sep 17 00:00:00 2001 From: Archil Date: Wed, 25 Sep 2024 18:09:05 +0400 Subject: [PATCH 04/46] Update erc-4626.md (#581) a minimal implementation broken link fixed: https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC4626.sol --- ERCS/erc-4626.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-4626.md b/ERCS/erc-4626.md index c28df5cba1..41de5ab9c0 100644 --- a/ERCS/erc-4626.md +++ b/ERCS/erc-4626.md @@ -576,7 +576,7 @@ For production implementations of Vaults which do not use EIP-4626, wrapper adap ## Reference Implementation -See [Solmate EIP-4626](https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol): +See [Solmate EIP-4626](https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC4626.sol): a minimal and opinionated implementation of the standard with hooks for developers to easily insert custom logic into deposits and withdrawals. See [Vyper EIP-4626](https://github.com/fubuloubu/ERC4626): From 34794c3bb3c52ac2a6b7cf29c3dd7d313e414f7e Mon Sep 17 00:00:00 2001 From: galimba Date: Wed, 25 Sep 2024 20:55:37 +0200 Subject: [PATCH 05/46] Update ERC-7208: Move to Review Merged by EIP-Bot. --- ERCS/erc-7208.md | 6 ++++-- assets/erc-7208/contracts/README.md | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 assets/erc-7208/contracts/README.md diff --git a/ERCS/erc-7208.md b/ERCS/erc-7208.md index 8b4d1d3f23..b175e8dec8 100644 --- a/ERCS/erc-7208.md +++ b/ERCS/erc-7208.md @@ -1,10 +1,10 @@ --- eip: 7208 title: On-Chain Data Container -description: ERC interoperability by abstracting logic away from storage +description: Interoperability by abstracting logic away from storage author: Rachid Ajaja , Alexandros Athanasopulos (@Xaleee), Pavel Rubin (@pash7ka), Sebastian Galimberti Romano (@galimba) discussions-to: https://ethereum-magicians.org/t/erc-7208-on-chain-data-container/14778 -status: Draft +status: Review type: Standards Track category: ERC created: 2023-06-09 @@ -271,6 +271,8 @@ We present an **educational example** implementation showcasing two types of tok **This example has not been audited and should not be used in production environments.** +See [contracts](../assets/eip-7208/contracts/README.md) + ## Security Considerations diff --git a/assets/erc-7208/contracts/README.md b/assets/erc-7208/contracts/README.md new file mode 100644 index 0000000000..2a0ea7707b --- /dev/null +++ b/assets/erc-7208/contracts/README.md @@ -0,0 +1,22 @@ +# Reference implementation of ERC-7208 and usage examples +## List of contracts +### Interfaces +- [IDataIndex](./interfaces/IDataIndex.sol) - Interface of Data Index +- [IDataObject](./interfaces/IDataObject.sol) - Interface of Data Object +- [IDataPointRegistry](./interfaces/IDataPointRegistry.sol) - Interface of Data Point Registry +- [IIDManager](./interfaces/IIDManager.sol) - Interface for buildinq and quering Data Index user identifiers + +### Implementation +- [DataIndex](./DataIndex.sol) - Data Index (implements `IDataIndex` and `IIDManager`) +- [DataPointRegistry](./DataPointRegistry.sol) - Data Point Registry (implements `IDataPointRegistry`) +- [DataPoints](./utils/DataPoints.sol) - Library implementing DataPoint type and its encode/decode functions +- [OmnichainAddresses](./utils/OmnichainAddresses.sol) - Library implementing OmnichainAddress type which combines address and chain id +- [ChainidTools](./utils/ChainidTools.sol) - Library implementing utility functions to work with chain ids + +### Usage examples +- [IFractionTransferEventEmitter](./interfaces/IFractionTransferEventEmitter.sol) - Interface used for DataManagers communication to emit ERC20 Transfer events +- [IFungibleFractionsOperations](./interfaces/IFungibleFractionsOperations.sol) - Interface defines DataObject operations, which can be called by DataManager +- [MinimalisticFungibleFractionsDO](./dataobjects/MinimalisticFungibleFractionsDO.sol) - DataObject implements data storage and related logic for token with Fungible Fractions (like ERC1155) +- [MinimalisticERC1155WithERC20FractionsDataManager](./datamanagers/MinimalisticERC1155WithERC20FractionsDataManager.sol) - DataManager implements token with fungible fractions with ERC1155 interface, linked to a DataManager which implements ERC20 interface for same token +- [MinimalisticERC20FractionDataManager](./datamanagers/MinimalisticERC20FractionDataManager.sol) - implements token with ERC20 interface, linked to a DataManager which implements ERC1155 interface for same token +- [MinimalisticERC20FractionDataManagerFactory](./datamanagers/MinimalisticERC20FractionDataManagerFactory.sol) - factory of DataManagers implementing ERC20 interface for token with fungible fractions \ No newline at end of file From 99e8c6af0bee797c5c6da549fafa8a129eaba81f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ernani=20S=C3=A3o=20Thiago?= Date: Thu, 26 Sep 2024 15:55:56 -0300 Subject: [PATCH 06/46] Update ERC-7432: Move to Final Merged by EIP-Bot. --- ERCS/erc-7432.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ERCS/erc-7432.md b/ERCS/erc-7432.md index 0708c4c36a..1043f65f67 100644 --- a/ERCS/erc-7432.md +++ b/ERCS/erc-7432.md @@ -4,8 +4,7 @@ title: Non-Fungible Token Roles description: Role Management for NFTs. Enables accounts to share the utility of NFTs via expirable role assignments. author: Ernani São Thiago (@ernanirst), Daniel Lima (@karacurt) discussions-to: https://ethereum-magicians.org/t/eip-7432-non-fungible-token-roles/15298 -status: Last Call -last-call-deadline: 2024-09-17 +status: Final type: Standards Track category: ERC created: 2023-07-14 From 82a7301d4f5d61190063a7b3327568fcdf1a419f Mon Sep 17 00:00:00 2001 From: Christina <156356273+cratiu222@users.noreply.github.com> Date: Fri, 27 Sep 2024 17:29:40 +0300 Subject: [PATCH 07/46] Update ERC-1066: Chore fix docs (#546) * correct spelling erc-1066.md * wrong verb form erc-1077.md * add missing verb erc-1081.md --- ERCS/erc-1066.md | 2 +- ERCS/erc-1077.md | 2 +- ERCS/erc-1081.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ERCS/erc-1066.md b/ERCS/erc-1066.md index 7f60fe566e..8b8c2a813a 100644 --- a/ERCS/erc-1066.md +++ b/ERCS/erc-1066.md @@ -236,7 +236,7 @@ Currently unspecified. (Full range reserved) #### `0x7*` TBD -Currently unspecifie. (Full range reserved) +Currently unspecified. (Full range reserved) #### `0x8*` TBD diff --git a/ERCS/erc-1077.md b/ERCS/erc-1077.md index 4ae82ddc2c..ca2a8a91f2 100644 --- a/ERCS/erc-1077.md +++ b/ERCS/erc-1077.md @@ -85,7 +85,7 @@ The fields **MUST** be constructed as this method: The first and second fields are to make it [EIP-191] compliant. Starting a transaction with `byte(0x19)` ensure the signed data from being a [valid ethereum transaction](https://github.com/ethereum/wiki/wiki/RLP). The second argument is a version control byte. The third being the validator address (the account contract address) according to version 0 of [EIP-191]. The remaining arguments being the application specific data for the gas relay: chainID as per [EIP-1344], execution nonce, execution data, agreed gas Price, gas limit of gas relayed call, gas token to pay back and gas relayer authorized to receive the reward. -The [EIP-191] message must be constructed as following: +The [EIP-191] message must be constructed as follows: ```solidity keccak256( abi.encodePacked( diff --git a/ERCS/erc-1081.md b/ERCS/erc-1081.md index f73b2c7011..bbb330361f 100644 --- a/ERCS/erc-1081.md +++ b/ERCS/erc-1081.md @@ -28,7 +28,7 @@ After studying bounties as they've existed for thousands of years (and after imp To implement these steps, a number of functions are needed: - `initializeBounty(address _issuer, address _arbiter, string _data, uint _deadline)`: This is used when deploying a new StandardBounty contract, and is particularly useful when applying the proxy design pattern, whereby bounties cannot be initialized in their constructors. Here, the data string should represent an IPFS hash, corresponding to a JSON object which conforms to the schema (described below). - `fulfillBounty(address[] _fulfillers, uint[] _numerators, uint _denomenator, string _data)`: This is called to submit a fulfillment, submitting a string representing an IPFS hash which contains the deliverable for the bounty. Initially fulfillments could only be submitted by one individual at a time, however users consistently told us they desired to be able to collaborate on fulfillments, thereby allowing the credit for submissions to be shared by several parties. The lines along which eventual payouts are split are determined by the fractions of the submission credited to each fulfiller (using the array of numerators and single denominator). Here, a bounty platform may also include themselves as a collaborator to collect a small fee for matching the bounty with fulfillers. -- `acceptFulfillment(uint _fulfillmentId, StandardToken[] _payoutTokens, uint[] _tokenAmounts)`: This is called by the `issuer` or the `arbiter` to pay out a given fulfillment, using an array of tokens, and an array of amounts of each token to be split among the contributors. This allows for the bounty payout amount to move as it needs to based on incoming contributions (which may be transferred directly to the contract address). It also allows for the easy splitting of a given bounty's balance among several fulfillments, if the need should arise. +- `acceptFulfillment(uint _fulfillmentId, StandardToken[] _payoutTokens, uint[] _tokenAmounts)`: This is called by the `issuer` or the `arbiter` to pay out a given fulfillment, using an array of tokens, and an array of amounts of each token to be split among the contributors. This allows for the bounty payout amount to move as it needs to be based on incoming contributions (which may be transferred directly to the contract address). It also allows for the easy splitting of a given bounty's balance among several fulfillments, if the need should arise. - `drainBounty(StandardToken[] _payoutTokens)`: This may be called by the `issuer` to drain a bounty of it's funds, if the need should arise. - `changeBounty(address _issuer, address _arbiter, string _data, uint _deadline)`: This may be called by the `issuer` to change the `issuer`, `arbiter`, `data`, and `deadline` fields of their bounty. - `changeIssuer(address _issuer)`: This may be called by the `issuer` to change to a new `issuer` if need be From e1b9b3ff82e7580379a62e3b0ae318414e1a2114 Mon Sep 17 00:00:00 2001 From: Jeroen <1748621+hieronx@users.noreply.github.com> Date: Fri, 27 Sep 2024 21:07:44 +0200 Subject: [PATCH 08/46] Update ERC-7741: Update ERC7741 (#560) * Move ERC7575 to Last Call * Clarifications * Fix reference implementation, add pipe explanation * Fix typo * Move ERC7540 to Last Call * requester => controller * chore: add author * fix: undo status change * comments * chore: some comments * Clarify request id * fix: explanation on requestRedeem * Swap nonce and deadline, update ERC165 id --------- Co-authored-by: Timepunk <45543880+0xTimepunk@users.noreply.github.com> Co-authored-by: Joey Santoro --- ERCS/erc-7741.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ERCS/erc-7741.md b/ERCS/erc-7741.md index 7c7c6f57d7..47ef38948c 100644 --- a/ERCS/erc-7741.md +++ b/ERCS/erc-7741.md @@ -77,10 +77,10 @@ MUST return `true`. type: address - name: approved type: bool - - name: deadline - type: uint256 - name: nonce type: bytes32 + - name: deadline + type: uint256 - name: signature type: bytes @@ -139,7 +139,7 @@ Returns the `DOMAIN_SEPARATOR` as defined according to EIP-712. The `DOMAIN_SEPA Smart contracts implementing this standard MUST implement the [ERC-165](./eip-165.md) `supportsInterface` function. -Contracts MUST return the constant value `true` if `0x7a7911eb` is passed through the `interfaceID` argument. +Contracts MUST return the constant value `true` if `0xa9e50872` is passed through the `interfaceID` argument. ## Rationale @@ -155,7 +155,7 @@ The main difference is using `bytes32` vs `uint256`, which enables unordered non // This code snippet is incomplete pseudocode used for example only and is no way intended to be used in production or guaranteed to be secure bytes32 public constant AUTHORIZE_OPERATOR_TYPEHASH = - keccak256("AuthorizeOperator(address controller,address operator,bool approved,uint256 deadline,bytes32 nonce)"); + keccak256("AuthorizeOperator(address controller,address operator,bool approved,bytes32 nonce,uint256 deadline)"); mapping(address owner => mapping(bytes32 nonce => bool used)) authorizations; @@ -171,8 +171,8 @@ The main difference is using `bytes32` vs `uint256`, which enables unordered non address controller, address operator, bool approved, - uint256 deadline, bytes32 nonce, + uint256 deadline, bytes memory signature ) external returns (bool success) { require(block.timestamp <= deadline, "ERC7540Vault/expired"); @@ -185,7 +185,7 @@ The main difference is using `bytes32` vs `uint256`, which enables unordered non abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), - keccak256(abi.encode(AUTHORIZE_OPERATOR_TYPEHASH, controller, operator, approved, deadline, nonce)) + keccak256(abi.encode(AUTHORIZE_OPERATOR_TYPEHASH, controller, operator, approved, nonce, deadline)) ) ); From 0fc375d6412fcab8e1de51131ba2f344fad5f32c Mon Sep 17 00:00:00 2001 From: Dexaran Date: Sat, 28 Sep 2024 00:45:36 +0100 Subject: [PATCH 09/46] Update ERC-7417: Update ERC-7417 Merged by EIP-Bot. --- ERCS/erc-7417.md | 672 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 570 insertions(+), 102 deletions(-) diff --git a/ERCS/erc-7417.md b/ERCS/erc-7417.md index 33b8b711af..5f2af30f98 100644 --- a/ERCS/erc-7417.md +++ b/ERCS/erc-7417.md @@ -15,11 +15,15 @@ requires: 20, 165, 223 There are multiple token standards on Ethereum chain currently. This EIP introduces a concept of cross-standard interoperability by creating a service that allows [ERC-20](./eip-20.md) tokens to be upgraded to [ERC-223](./eip-223.md) tokens anytime. [ERC-223](./eip-223.md) tokens can be converted back to [ERC-20](./eip-20.md) version without any restrictions to avoid any problems with backwards compatibility and allow different standards to co-exist and become interoperable and interchangeable. -To perform the conversion, the user must send tokens of one standard to the Converter contract and he will automatically receive tokens of another standard. +In order to perform the conversion, a user must deposit tokens of one standard to the Converter contract and it will automatically send tokens of another standard back. ## Motivation -When an ERC-20 contract is upgraded, finding the new address introduces risk. This proposal creates a service that performs token conversion and prevents potentially unsafe implementations from spreading. +This proposal introduces a concept of token standard upgrading procedure driven by a specialized smart-contract which can convert tokens of one standard to another at any time as well as create an alternative version of any existing token of the older standard. + +Currently some tokens are available on different chains in different standards, for example most exchanges support [ERC-20](./eip-20.md) USDT, TRX USDT, BEP-20 USDT and all this tokens are in fact the same USDT token. This proposal is intended to introduce a concept where there can be a [ERC-20](./eip-20.md) USDT and [ERC-223](./eip-223.md) USDT available on Ethereum mainnet at the same time and both can co-exist. + +The address of the deployed Token Converter must be described here as to solve the trust issues for the token developers and help them figure out a proper way of interacting with the Converter. ## Specification @@ -41,21 +45,54 @@ Converter contract MUST accept deposits of [ERC-223](./eip-223.md) tokens and se #### Conver contract methods -##### `getWrapperFor` +##### `getERC20WrapperFor` + +```solidity +function getERC20WrapperFor(address _token) public view returns (address) +``` + +Returns the address of the [ERC-20](./eip-20.md) wrapper for a given token address. Returns `0x0` if there is no [ERC-20](./eip-20.md) version for the provided token address. There can be exactly one wrapper for any given [ERC-223](./eip-223.md) token address created by the Token Converter contract. + +##### `getERC223WrapperFor` ```solidity -function getWrapperFor(address _erc20Token) public view returns (address) +function getERC223WrapperFor(address _token) public view returns (address) ``` -Returns the address of the [ERC-223](./eip-223.md) wrapper for a given [ERC-20](./eip-20.md) original token. Returns `0x0` if there is no [ERC-223](./eip-223.md) version for the provided [ERC-20](./eip-20.md) token address. There MUST be exactly one wrapper for any given [ERC-20](./eip-20.md) token address created by the Token Converter contract. +Returns the address of the [ERC-223](./eip-223.md) wrapper for a given token address. Returns `0x0` if there is no [ERC-223](./eip-223.md) version for the provided token address. There can be exactly one [ERC-223](./eip-223.md) wrapper for any given [ERC-20](./eip-20.md) token address created by the Token Converter contract. -##### `getOriginFor` +##### `getERC20OriginFor` ```solidity -function getOriginFor(address _erc223Token) public view returns (address) +function getERC20OriginFor(address _erc223Token) public view returns (address) ``` -Returns the address of the original [ERC-20](./eip-20.md) token for a given [ERC-223](./eip-223.md) wrapper. Returns `0x0` if the provided `_erc223Token` is not an address of any [ERC-223](./eip-223.md) wrapper created by the Token Converter contract. +Returns the address of the original [ERC-20](./eip-20.md) token for the provided [ERC-223](./eip-223.md) wrapper. Returns `0x0` if the provided `_erc223Token` is not an address of any [ERC-223](./eip-223.md) wrapper created by the Token Converter contract. + +##### `getERC223OriginFor` + +```solidity +function getERC223OriginFor(address _erc20Token) public view returns (address) +``` + +Returns the address of the original [ERC-223](./eip-223.md) token for the provided [ERC-20](./eip-20.md) wrapper. Returns `0x0` if the provided `_erc20Token` is not an address of any wrapper created by the Token Converter contract. + +##### `predictWrapperAddress` + +```solidity +function predictWrapperAddress(address _token, + bool _isERC20 // Is the provided _token a ERC-20 or not? + // If it is set as ERC-20 then we will predict the address of a + // ERC-223 wrapper for that token. + // Otherwise we will predict ERC-20 wrapper address. + ) view external returns (address) +``` + +Wrapper contracts are deployed via `CREATE2` opcode and it is possible to predict the address of a wrapper which is not yet deployed. The address of a wrapper contract depends on the bytecode therefore it is necessary to specify if the address of wrapper [ERC-20](./eip-20.md) or wrapper [ERC-223](./eip-223.md) must be predicted. + +Providing `_token` address and `_isERC20 = false` will result in [ERC-20](./eip-20.md) wrapper address being predicted. + +Providing `_token` address and `_isERC20 = true` will result in [ERC-223](./eip-223.md) wrapper address being predicted. ##### `createERC223Wrapper` @@ -63,19 +100,66 @@ Returns the address of the original [ERC-20](./eip-20.md) token for a given [ERC function createERC223Wrapper(address _erc20Token) public returns (address) ``` -Creates a new [ERC-223](./eip-223.md) wrapper for a given `_erc20Token` if it does not exist yet. Reverts the transaction if the wrapper already exist. Returns the address of the new wrapper token contract on success. +Creates a new [ERC-223](./eip-223.md) wrapper for a given `_erc20Token` if it does not exist yet. Reverts the transaction if the wrapper already exist. Returns the address of the new wrapper token contract on success. Reverts if `_erc223Token` is a wrapper created by the Converter. + +The deployed contract will be a standard [ERC-223](./eip-223.md) token with `approve` and `transferFrom` functions implemented for backwards compatibility. + +All [ERC-223](./eip-223.md) wrappers deployed by the Converter will have `standard() pure returns (bytes32)` function implemented which returns `223`. This serves further token standard introspection as [ERC-165](./eip-165.md) may not be reliable when dealing with identifying the internal logic implemented within `transfer` function of a token. -##### `convertERC20toERC223` +NOTE: This function does not verify the standard of `_erc20Token` because there is no reliable method of introspection available which could guarantee that the provided token implements a particular standard. As the result it is possible to create a [ERC-223](./eip-223.md) wrapper for an original [ERC-223](./eip-223.md) token. + +##### `createERC20Wrapper` ```solidity -function convertERC20toERC223(address _erc20token, uint256 _amount) public returns (bool) +function createERC20Wrapper(address _erc223Token) public returns (address) ``` -Withdraws `_amount` of [ERC-20](./eip-20.md) token from the transaction senders balance with `transferFrom` function. Sends the `_amount` of [ERC-223](./eip-223.md) wrapper tokens to the sender of the transaction. Stores the original tokens at the balance of the Token Converter contract for future claims. Returns `true` on success. The Token Converter must keep record of the amount of [ERC-20](./eip-20.md) tokens that were deposited with `convertERC20toERC223` function because it is possible to deposit [ERC-20](./eip-20.md) tokens to any contract by directly sending them with `transfer` function. +Creates a new [ERC-20](./eip-20.md) wrapper for a given `_erc223Token` if it does not exist yet. Reverts the transaction if the wrapper already exist. Returns the address of the new wrapper token contract on success. Reverts if `_erc223Token` is a wrapper created by the Converter. + +NOTE: This function does not verify the standard of `_erc223Token` because there is no reliable method of introspection available which could guarantee that the provided token implements a particular standard. As the result it is possible to create a [ERC-20](./eip-20.md) wrapper for an original [ERC-20](./eip-20.md) token. + +##### `wrapERC20toERC223` + +```solidity +function wrapERC20toERC223(address _ERC20token, uint256 _amount) public returns (bool) +``` + +Withdraws `_amount` of [ERC-20](./eip-20.md) tokens from the transaction sender with `transferFrom` function. Delivers the `_amount` of [ERC-223](./eip-223.md) wrapper tokens to the sender of the transaction. Stores the original tokens at the balance of the Token Converter contract for future claims. Returns `true` on success. The Token Converter must keep record of the amount of [ERC-20](./eip-20.md) tokens that were deposited with `wrapERC20toERC223` function because it is possible to deposit [ERC-20](./eip-20.md) tokens to any contract by directly sending them with `transfer` function. If there is no [ERC-223](./eip-223.md) wrapper for the `_ERC20token` then creates it by calling a `createERC223Wrapper(_erc20toke)` function. -If the provided `_erc20token` address is an address of a [ERC-223](./eip-223.md) wrapper reverts the transaction. +There is no special function to unwrap [ERC-223](./eip-223.md) wrappers to [ERC-20](./eip-20.md) origin as this logic is implemented in the `tokenReceived` function of the Converter. + +##### `unwrapERC20toERC223` + +```solidity +function unwrapERC20toERC223(address _ERC20token, uint256 _amount) public returns (bool) +``` + +Withdraws `_amount` of [ERC-20](./eip-20.md) tokens from the transaction sender with `transferFrom` function. Delivers the `_amount` of [ERC-223](./eip-223.md) wrapper tokens to the sender of the transaction. Stores the original tokens at the balance of the Token Converter contract for future claims. Returns `true` on success. The Token Converter must keep record of the amount of [ERC-20](./eip-20.md) tokens that were deposited with `wrapERC20toERC223` function because it is possible to deposit [ERC-20](./eip-20.md) tokens to any contract by directly sending them with `transfer` function. + +If there is no [ERC-223](./eip-223.md) wrapper for the `_ERC20token` then creates it by calling a `createERC223Wrapper(_erc20toke)` function. + + +##### `convertERC20` + +```solidity +function convertERC20(address _token, uint256 _amount) public returns (bool) +``` + +Automatically determines if the provided [ERC-20](./eip-20.md) token is a wrapper or not. If it is a wrapper then executes `unwrapERC20toERC223` function. If the provided token is an origin then executes `wrapERC20toERC223` function. + +This function is implemented to significantly simplify the workflow of services that integrate both versions of one token in the same contract and need to automatically convert tokens through the Converter. + +##### `isWrapper` + +```solidity +function isWrapper(address _token) public view returns (bool) +``` + +Returns `true` if the provided `_token` address is an address of a wrapper created by the Converter. + +NOTE: This function does not identify the standard of a `_token`. There can be exactly one origin for any wrapper created by the Converter. However an original token can have two wrappers, one of each standard. ##### `tokenReceived` @@ -83,23 +167,23 @@ If the provided `_erc20token` address is an address of a [ERC-223](./eip-223.md) function tokenReceived(address _from, uint _value, bytes memory _data) public override returns (bytes4) ``` -This is a standard [ERC-223](./eip-223.md) transaction handler function and it is called by the [ERC-223](./eip-223.md) token contract when `_from` is sending `_value` of [ERC-223](./eip-223.md) tokens to `address(this)` address. In the scope of this function `msg.sender` is the address of the [ERC-223](./eip-223.md) token contract and `_from` is the initiator of the transaction. +This is a standard [ERC-223](./eip-223.md) transaction handler function and it is called by the [ERC-223](./eip-223.md) token contract when `_from` is sending `_value` of [ERC-223](./eip-223.md) tokens to `address(this)` address. In the scope of this function `msg.sender` is the address of the [ERC-223](./eip-223.md) token contract and `_from` is the sender of the token transfer. -If `msg.sender` is an address of [ERC-223](./eip-223.md) wrapper created by the Token Converter then `_value` of [ERC-20](./eip-20.md) original token must be sent to the `_from` address. +Automatically determines -If `msg.sender` is not an address of any [ERC-223](./eip-223.md) wrapper known to the Token Converter then revert the transaction thus returning any `ERC-223` tokens back to the sender. +If `msg.sender` is an address of [ERC-223](./eip-223.md) wrapper created by the Token Converter then `_value` of [ERC-20](./eip-20.md) original token must be sent to the `_from` address. -This is the function that MUST be used to convert [ERC-223](./eip-223.md) wrapper tokens back to original [ERC-20](./eip-20.md) tokens. This function is automatically executed when [ERC-223](./eip-223.md) tokens are sent to the address of the Token Converter. If any arbitrary [ERC-223](./eip-223.md) token is sent to the Token Converter it will be rejected. +If `msg.sender` is not an address of any [ERC-223](./eip-223.md) wrapper known to the Token Converter then it is considered a [ERC-223](./eip-223.md) origin and `_value` amount of [ERC-20](./eip-20.md) wrapper tokens must be sent to the `_from` address. If the [ERC-20](./eip-20.md) wrapper for the `msg.sender` token does not exist then create it first. Returns `0x8943ec02`. -##### `rescueERC20` +##### `extractStuckERC20` ```solidity -function rescueERC20(address _token) external +function extractStuckERC20(address _token) ``` -This function allows to extract the [ERC-20](./eip-20.md) tokens that were directly deposited to the contract with `transfer` function to prevent users who may send tokens by mistake from permanently freezing their assets. Since the Token Converter calculates the amount of tokens that were deposited legitimately with `convertERC20toERC223` function it is always possible to calculate the amount of "accidentally deposited tokens" by subtracting the recorded amount from the returned value of the `balanceOf( address(this) )` function called on the [ERC-20](./eip-20.md) token contract. +This function allows to extract the [ERC-20](./eip-20.md) tokens that were directly deposited to the contract with `transfer` function to prevent users who may send tokens by mistake from permanently losing their tokens. Since the Token Converter calculates the amount of tokens that were deposited legitimately with `convertERC20toERC223` function it is always possible to calculate the amount of "accidentally deposited tokens" by subtracting the recorded amount from the returned value of the `balanceOf( address(this) )` function called on the [ERC-20](./eip-20.md) token contract. ### Converting [ERC-20](./eip-20.md) tokens to [ERC-223](./eip-223.md) @@ -117,15 +201,27 @@ In order to convert [ERC-20](./eip-20.md) tokens to [ERC-223](./eip-223.md) the ## Rationale - +For example it was a common case with [ERC-20](./eip-20.md) where developers could implement custom logic of the `transfer` function and mess the return values. The [ERC-20](./eip-20.md) specification declares that a `transfer` function MUST return a `bool` value, however in practice we have three different types of [ERC-20](./eip-20.md) tokens which are not compatible with each other: -TBD +1. [ERC-20](./eip-20.md) tokens that return `true` on success and revert on an error. +2. [ERC-20](./eip-20.md) tokens that return `true` on success and `false` on an error without reverting the transaction. +3. [ERC-20](./eip-20.md) tokens that don't have return values and revert on an error. + +Technically the third category of tokens is not compatible with [ERC-20](./eip-20.md) standard. However, USDT token deployed on Ethereum mainnet at `0xdac17f958d2ee523a2206206994597c13d831ec7` address does not implement return values and it is one of the most used tokens and it is not an option to deny supporting USDT due to it's improper implementation of the standard. + +The Token Converter eliminates the issue where different development teams may implement the standard with slight modifications and result in a situation where we would have different versions of the same standard on the mainnet. + +At the same time the Converter enables the concurrent token support in other smart-contracts, such as decentralized exchanges. The Converter can guarantee that a pair of two tokens one of which is a wrapper for another is in fact the same token that can be converted from one standard to another at any time. This enables the creation of liquidity pools where two different tokens are dealt with as if they were one token while in fact these are exactly one token available in different standards. ## Backwards Compatibility @@ -136,7 +232,389 @@ This service is the first of its kind and therefore does not have any backwards ## Reference Implementation ```solidity - address public ownerMultisig; + +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity =0.8.19; + +library Address { + function isContract(address account) internal view returns (bool) { + // This method relies on extcodesize, which returns 0 for contracts in + // construction, since the code is only stored at the end of the + // constructor execution. + + uint256 size; + // solhint-disable-next-line no-inline-assembly + assembly { size := extcodesize(account) } + return size > 0; + } +} + +interface IERC20 { + function totalSupply() external view returns (uint256); + function balanceOf(address account) external view returns (uint256); + function transfer(address recipient, uint256 amount) external returns (bool); + function allowance(address owner, address spender) external view returns (uint256); + function approve(address spender, uint256 amount) external returns (bool); + function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); +} + +interface IERC20Metadata is IERC20 { + /// @return The name of the token + function name() external view returns (string memory); + + /// @return The symbol of the token + function symbol() external view returns (string memory); + + /// @return The number of decimal places the token has + function decimals() external view returns (uint8); +} + +abstract contract IERC223Recipient { + function tokenReceived(address _from, uint _value, bytes memory _data) public virtual returns (bytes4) + { + return 0x8943ec02; + } +} + +abstract contract ERC165 { + /* + * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7 + */ + bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; + mapping(bytes4 => bool) private _supportedInterfaces; + + constructor () { + // Derived contracts need only register support for their own interfaces, + // we register support for ERC165 itself here + _registerInterface(_INTERFACE_ID_ERC165); + } + function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { + return _supportedInterfaces[interfaceId]; + } + function _registerInterface(bytes4 interfaceId) internal virtual { + require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); + _supportedInterfaces[interfaceId] = true; + } +} + +abstract contract IERC223 { + function name() public view virtual returns (string memory); + function symbol() public view virtual returns (string memory); + function decimals() public view virtual returns (uint8); + function totalSupply() public view virtual returns (uint256); + function balanceOf(address who) public virtual view returns (uint); + function transfer(address to, uint value) public virtual returns (bool success); + function transfer(address to, uint value, bytes calldata data) public payable virtual returns (bool success); + event Transfer(address indexed from, address indexed to, uint value, bytes data); +} + +interface standardERC20 +{ + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); + function totalSupply() external view returns (uint256); + function balanceOf(address account) external view returns (uint256); + function transfer(address to, uint256 value) external returns (bool); + function allowance(address owner, address spender) external view returns (uint256); + function approve(address spender, uint256 value) external returns (bool); + function transferFrom(address from, address to, uint256 value) external returns (bool); +} + +/** + * @dev Interface of the ERC20 standard as defined in the EIP. + */ +interface IERC223WrapperToken { + function name() external view returns (string memory); + function symbol() external view returns (string memory); + function decimals() external view returns (uint8); + function standard() external view returns (string memory); + function origin() external view returns (address); + + function totalSupply() external view returns (uint256); + function balanceOf(address account) external view returns (uint256); + function transfer(address to, uint256 value) external payable returns (bool); + function transfer(address to, uint256 value, bytes calldata data) external payable returns (bool); + function allowance(address owner, address spender) external view returns (uint256); + function approve(address spender, uint256 value) external returns (bool); + function transferFrom(address from, address to, uint256 value) external returns (bool); + + function mint(address _recipient, uint256 _quantity) external; + function burn(address _recipient, uint256 _quantity) external; +} + +interface IERC20WrapperToken { + function name() external view returns (string memory); + function symbol() external view returns (string memory); + function decimals() external view returns (uint8); + function standard() external view returns (string memory); + function origin() external view returns (address); + + function totalSupply() external view returns (uint256); + function balanceOf(address account) external view returns (uint256); + function transfer(address to, uint256 value) external returns (bool); + function allowance(address owner, address spender) external view returns (uint256); + function approve(address spender, uint256 value) external returns (bool); + function transferFrom(address from, address to, uint256 value) external returns (bool); + + function mint(address _recipient, uint256 _quantity) external; + function burn(address _recipient, uint256 _quantity) external; +} + +contract ERC20Rescue +{ + // ERC-20 tokens can get stuck on a contracts balance due to lack of error handling. + // + // The author of the ERC-7417 can extract ERC-20 tokens if they are mistakenly sent + // to the wrapper-contracts balance. + // Contact dexaran@ethereumclassic.org + address public extractor = 0x01000B5fE61411C466b70631d7fF070187179Bbf; + + function safeTransfer(address token, address to, uint value) internal { + // bytes4(keccak256(bytes('transfer(address,uint256)'))); + (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); + require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED'); + } + + function rescueERC20(address _token, uint256 _amount) external + { + safeTransfer(_token, extractor, _amount); + } +} + +contract ERC223WrapperToken is IERC223, ERC165, ERC20Rescue +{ + address public creator = msg.sender; + address private wrapper_for; + + mapping(address account => mapping(address spender => uint256)) private allowances; + + event Transfer(address indexed from, address indexed to, uint256 amount); + event TransferData(bytes data); + event Approval(address indexed owner, address indexed spender, uint256 amount); + + function set(address _wrapper_for) external + { + require(msg.sender == creator); + wrapper_for = _wrapper_for; + } + + uint256 private _totalSupply; + + mapping(address => uint256) private balances; // List of user balances. + + function totalSupply() public view override returns (uint256) { return _totalSupply; } + function balanceOf(address _owner) public view override returns (uint256) { return balances[_owner]; } + + + /** + * @dev The ERC165 introspection function. + */ + function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { + return + interfaceId == type(IERC20).interfaceId || + interfaceId == type(standardERC20).interfaceId || + interfaceId == type(IERC223WrapperToken).interfaceId || + interfaceId == type(IERC223).interfaceId || + super.supportsInterface(interfaceId); + } + + /** + * @dev Standard ERC-223 transfer function. + * Calls _to if it is a contract. Does not transfer tokens to contracts + * which do not explicitly declare the tokenReceived function. + * @param _to - transfer recipient. Can be contract or EOA. + * @param _value - the quantity of tokens to transfer. + * @param _data - metadata to send alongside the transaction. Can be used to encode subsequent calls in the recipient. + */ + function transfer(address _to, uint _value, bytes calldata _data) public payable override returns (bool success) + { + balances[msg.sender] = balances[msg.sender] - _value; + balances[_to] = balances[_to] + _value; + if(Address.isContract(_to)) { + IERC223Recipient(_to).tokenReceived(msg.sender, _value, _data); + } + if (msg.value > 0) payable(_to).transfer(msg.value); + emit Transfer(msg.sender, _to, _value, _data); + emit Transfer(msg.sender, _to, _value); // Old ERC-20 compatible event. Added for backwards compatibility reasons. + + return true; + } + + /** + * @dev Standard ERC-223 transfer function without _data parameter. It is supported for + * backwards compatibility with ERC-20 services. + * Calls _to if it is a contract. Does not transfer tokens to contracts + * which do not explicitly declare the tokenReceived function. + * @param _to - transfer recipient. Can be contract or EOA. + * @param _value - the quantity of tokens to transfer. + */ + function transfer(address _to, uint _value) public override returns (bool success) + { + bytes memory _empty = hex"00000000"; + balances[msg.sender] = balances[msg.sender] - _value; + balances[_to] = balances[_to] + _value; + if(Address.isContract(_to)) { + IERC223Recipient(_to).tokenReceived(msg.sender, _value, _empty); + } + emit Transfer(msg.sender, _to, _value, _empty); + emit Transfer(msg.sender, _to, _value); // Old ERC-20 compatible event. Added for backwards compatibility reasons. + + return true; + } + + function name() public view override returns (string memory) { return IERC20Metadata(wrapper_for).name(); } + function symbol() public view override returns (string memory) { return string.concat(IERC20Metadata(wrapper_for).name(), "223"); } + function decimals() public view override returns (uint8) { return IERC20Metadata(wrapper_for).decimals(); } + function standard() public pure returns (uint32) { return 223; } + function origin() public view returns (address) { return wrapper_for; } + + + /** + * @dev Minting function which will only be called by the converter contract. + * @param _recipient - the address which will receive tokens. + * @param _quantity - the number of tokens to create. + */ + function mint(address _recipient, uint256 _quantity) external + { + require(msg.sender == creator, "Wrapper Token: Only the creator contract can mint wrapper tokens."); + balances[_recipient] += _quantity; + _totalSupply += _quantity; + } + + /** + * @dev Burning function which will only be called by the converter contract. + * @param _quantity - the number of tokens to destroy. TokenConverter can only destroy tokens on it's own address. + * Only the token converter is allowed to burn wrapper-tokens. + */ + function burn(uint256 _quantity) external + { + require(msg.sender == creator, "Wrapper Token: Only the creator contract can destroy wrapper tokens."); + balances[msg.sender] -= _quantity; + _totalSupply -= _quantity; + } + + // ERC-20 functions for backwards compatibility. + + function allowance(address owner, address spender) public view virtual returns (uint256) { + return allowances[owner][spender]; + } + + function approve(address _spender, uint _value) public returns (bool) { + + // Safety checks. + require(_spender != address(0), "ERC-223: Spender error."); + + allowances[msg.sender][_spender] = _value; + emit Approval(msg.sender, _spender, _value); + + return true; + } + + function transferFrom(address _from, address _to, uint _value) public returns (bool) { + + require(allowances[_from][msg.sender] >= _value, "ERC-223: Insufficient allowance."); + + balances[_from] -= _value; + allowances[_from][msg.sender] -= _value; + balances[_to] += _value; + + emit Transfer(_from, _to, _value); + + return true; + } +} + +contract ERC20WrapperToken is IERC20, ERC165, ERC20Rescue +{ + address public creator = msg.sender; + address public wrapper_for; + + mapping(address account => mapping(address spender => uint256)) private allowances; + + function set(address _wrapper_for) external + { + require(msg.sender == creator); + wrapper_for = _wrapper_for; + } + + uint256 private _totalSupply; + mapping(address => uint256) private balances; // List of user balances. + + + function balanceOf(address _owner) public view override returns (uint256) { return balances[_owner]; } + + function name() public view returns (string memory) { return IERC20Metadata(wrapper_for).name(); } + function symbol() public view returns (string memory) { return string.concat(IERC223(wrapper_for).name(), "20"); } + function decimals() public view returns (uint8) { return IERC20Metadata(wrapper_for).decimals(); } + function totalSupply() public view override returns (uint256) { return _totalSupply; } + function origin() public view returns (address) { return wrapper_for; } + + function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { + return + interfaceId == type(IERC20).interfaceId || + interfaceId == type(IERC20WrapperToken).interfaceId || + super.supportsInterface(interfaceId); + } + + function transfer(address _to, uint _value) public override returns (bool success) + { + balances[msg.sender] = balances[msg.sender] - _value; + balances[_to] = balances[_to] + _value; + emit Transfer(msg.sender, _to, _value); + return true; + } + + function mint(address _recipient, uint256 _quantity) external + { + require(msg.sender == creator, "Wrapper Token: Only the creator contract can mint wrapper tokens."); + balances[_recipient] += _quantity; + _totalSupply += _quantity; + } + + function burn(address _from, uint256 _quantity) external + { + require(msg.sender == creator, "Wrapper Token: Only the creator contract can destroy wrapper tokens."); + balances[_from] -= _quantity; + _totalSupply -= _quantity; + } + + function allowance(address owner, address spender) public view virtual returns (uint256) { + return allowances[owner][spender]; + } + + function approve(address _spender, uint _value) public returns (bool) { + + // Safety checks. + + require(_spender != address(0), "ERC-20: Spender error."); + + allowances[msg.sender][_spender] = _value; + emit Approval(msg.sender, _spender, _value); + + return true; + } + + function transferFrom(address _from, address _to, uint _value) public returns (bool) { + + require(allowances[_from][msg.sender] >= _value, "ERC-20: Insufficient allowance."); + + balances[_from] -= _value; + allowances[_from][msg.sender] -= _value; + balances[_to] += _value; + + emit Transfer(_from, _to, _value); + + return true; + } +} + +contract TokenStandardConverter is IERC223Recipient +{ + event ERC223WrapperCreated(address indexed _token, address indexed _ERC223Wrapper); + event ERC20WrapperCreated(address indexed _token, address indexed _ERC20Wrapper); mapping (address => ERC223WrapperToken) public erc223Wrappers; // A list of token wrappers. First one is ERC-20 origin, second one is ERC-223 version. mapping (address => ERC20WrapperToken) public erc20Wrappers; @@ -145,24 +623,14 @@ This service is the first of its kind and therefore does not have any backwards mapping (address => address) public erc20Origins; mapping (address => uint256) public erc20Supply; // Token => how much was deposited. - function getERC20WrapperFor(address _token) public view returns (address, string memory) + function getERC20WrapperFor(address _token) public view returns (address) { - if ( address(erc20Wrappers[_token]) != address(0) ) - { - return (address(erc20Wrappers[_token]), "ERC-20"); - } - - return (address(0), "Error"); + return address(erc20Wrappers[_token]); } - function getERC223WrapperFor(address _token) public view returns (address, string memory) + function getERC223WrapperFor(address _token) public view returns (address) { - if ( address(erc223Wrappers[_token]) != address(0) ) - { - return (address(erc223Wrappers[_token]), "ERC-223"); - } - - return (address(0), "Error"); + return address(erc223Wrappers[_token]); } function getERC20OriginFor(address _token) public view returns (address) @@ -175,7 +643,33 @@ This service is the first of its kind and therefore does not have any backwards return (address(erc223Origins[_token])); } - function tokenReceived(address _from, uint _value, bytes memory _data) public override returns (bytes4) + function predictWrapperAddress(address _token, + bool _isERC20 // Is the provided _token a ERC-20 or not? + // If it is set as ERC-20 then we will predict the address of a + // ERC-223 wrapper for that token. + // Otherwise we will predict ERC-20 wrapper address. + ) view external returns (address) + { + bytes memory _bytecode; + if(_isERC20) + { + _bytecode= type(ERC223WrapperToken).creationCode; + } + else + { + _bytecode= type(ERC20WrapperToken).creationCode; + } + + bytes32 hash = keccak256( + abi.encodePacked( + bytes1(0xff), address(this), keccak256(abi.encode(_token)), keccak256(_bytecode) + ) + ); + + return address(uint160(uint(hash))); + } + + function tokenReceived(address _from, uint _value, bytes memory /* _data */) public override returns (bytes4) { require(erc223Origins[msg.sender] == address(0), "Error: creating wrapper for a wrapper token."); // There are two possible cases: @@ -187,12 +681,11 @@ This service is the first of its kind and therefore does not have any backwards // Origin for deposited token exists. // Unwrap ERC-223 wrapper. + erc20Supply[erc20Origins[msg.sender]] -= _value; safeTransfer(erc20Origins[msg.sender], _from, _value); - erc20Supply[erc20Origins[msg.sender]] -= _value; - //erc223Wrappers[msg.sender].burn(_value); ERC223WrapperToken(msg.sender).burn(_value); - + return this.tokenReceived.selector; } // Otherwise origin for the sender token doesn't exist @@ -204,7 +697,7 @@ This service is the first of its kind and therefore does not have any backwards // Create ERC-20 wrapper if it doesn't exist. createERC20Wrapper(msg.sender); } - + // Mint ERC-20 wrapper tokens for the deposited ERC-223 token // if the ERC-20 wrapper didn't exist then it was just created in the above statement. erc20Wrappers[msg.sender].mint(_from, _value); @@ -214,38 +707,31 @@ This service is the first of its kind and therefore does not have any backwards function createERC223Wrapper(address _token) public returns (address) { require(address(erc223Wrappers[_token]) == address(0), "ERROR: Wrapper exists"); - require(getERC20OriginFor(_token) == address(0), "ERROR: 20 wrapper creation"); - require(getERC223OriginFor(_token) == address(0), "ERROR: 223 wrapper creation"); - - ERC223WrapperToken _newERC223Wrapper = new ERC223WrapperToken(_token); + require(!isWrapper(_token), "Error: Creating wrapper for a wrapper token"); + + ERC223WrapperToken _newERC223Wrapper = new ERC223WrapperToken{salt: keccak256(abi.encode(_token))}(); + _newERC223Wrapper.set(_token); erc223Wrappers[_token] = _newERC223Wrapper; erc20Origins[address(_newERC223Wrapper)] = _token; + emit ERC223WrapperCreated(_token, address(_newERC223Wrapper)); return address(_newERC223Wrapper); } function createERC20Wrapper(address _token) public returns (address) { require(address(erc20Wrappers[_token]) == address(0), "ERROR: Wrapper already exists."); - require(getERC20OriginFor(_token) == address(0), "ERROR: 20 wrapper creation"); - require(getERC223OriginFor(_token) == address(0), "ERROR: 223 wrapper creation"); + require(!isWrapper(_token), "Error: Creating wrapper for a wrapper token"); - ERC20WrapperToken _newERC20Wrapper = new ERC20WrapperToken(_token); + ERC20WrapperToken _newERC20Wrapper = new ERC20WrapperToken{salt: keccak256(abi.encode(_token))}(); + _newERC20Wrapper.set(_token); erc20Wrappers[_token] = _newERC20Wrapper; erc223Origins[address(_newERC20Wrapper)] = _token; + emit ERC20WrapperCreated(_token, address(_newERC20Wrapper)); return address(_newERC20Wrapper); } - function depositERC20(address _token, uint256 _amount) public returns (bool) - { - if(erc223Origins[_token] != address(0)) - { - return unwrapERC20toERC223(_token, _amount); - } - else return wrapERC20toERC223(_token, _amount); - } - function wrapERC20toERC223(address _ERC20token, uint256 _amount) public returns (bool) { // If there is no active wrapper for a token that user wants to wrap @@ -256,14 +742,12 @@ This service is the first of its kind and therefore does not have any backwards } uint256 _converterBalance = IERC20(_ERC20token).balanceOf(address(this)); // Safety variable. safeTransferFrom(_ERC20token, msg.sender, address(this), _amount); - - erc20Supply[_ERC20token] += _amount; - require( - IERC20(_ERC20token).balanceOf(address(this)) - _amount == _converterBalance, - "ERROR: The transfer have not subtracted tokens from callers balance."); + _amount = IERC20(_ERC20token).balanceOf(address(this)) - _converterBalance; + erc20Supply[_ERC20token] += _amount; erc223Wrappers[_ERC20token].mint(msg.sender, _amount); + return true; } @@ -273,48 +757,30 @@ This service is the first of its kind and therefore does not have any backwards require(erc223Origins[_ERC20token] != address(0), "Error: provided token is not a ERC-20 wrapper."); ERC20WrapperToken(_ERC20token).burn(msg.sender, _amount); - IERC223(erc223Origins[_ERC20token]).transfer(msg.sender, _amount); + + safeTransfer(erc223Origins[_ERC20token], msg.sender, _amount); return true; } - function isWrapper(address _token) public view returns (bool) - { - return erc20Origins[_token] != address(0) || erc223Origins[_token] != address(0); - } - -/* - function convertERC223toERC20(address _from, uint256 _amount) public returns (bool) + function convertERC20(address _token, uint256 _amount) public returns (bool) { - // If there is no active wrapper for a token that user wants to wrap - // then create it. - if(address(erc20Wrappers[msg.sender]) == address(0)) - { - createERC223Wrapper(msg.sender); - } - - erc20Wrappers[msg.sender].mint(_from, _amount); - return true; + if(isWrapper(_token)) return unwrapERC20toERC223(_token, _amount); + else return wrapERC20toERC223(_token, _amount); } -*/ - function rescueERC20(address _token) external { - require(msg.sender == ownerMultisig, "ERROR: Only owner can do this."); - uint256 _stuckTokens = IERC20(_token).balanceOf(address(this)) - erc20Supply[_token]; - safeTransfer(_token, msg.sender, IERC20(_token).balanceOf(address(this))); + function isWrapper(address _token) public view returns (bool) + { + return erc20Origins[_token] != address(0) || erc223Origins[_token] != address(0); } - function transferOwnership(address _newOwner) public + function extractStuckERC20(address _token) external { - require(msg.sender == ownerMultisig, "ERROR: Only owner can call this function."); - ownerMultisig = _newOwner; + require(msg.sender == address(0x01000B5fE61411C466b70631d7fF070187179Bbf)); + + safeTransfer(_token, address(0x01000B5fE61411C466b70631d7fF070187179Bbf), IERC20(_token).balanceOf(address(this)) - erc20Supply[_token]); } - // ************************************************************ - // Functions that address problems with tokens that pretend to be ERC-20 - // but in fact are not compatible with the ERC-20 standard transferring methods. - // EIP20 https://eips.ethereum.org/EIPS/eip-20 - // ************************************************************ function safeTransfer(address token, address to, uint value) internal { // bytes4(keccak256(bytes('transfer(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); @@ -326,16 +792,18 @@ This service is the first of its kind and therefore does not have any backwards (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED'); } - +} ``` ## Security Considerations -1. While it is possible to implement a service that converts any token standard to any other standard - it is better to keep different standard convertors separate from one another as different standards may contain specific logic. Therefore this proposal focuses on [ERC-20](./eip-20.md) to [ERC-223](./eip-223.md) conversion methods. -2. [ERC-20](./eip-20.md) tokens can be deposited to any contract directly with `transfer` function. This may result in a permanent loss of tokens because it is not possible to recognize this transaction on the recipients side. `rescueERC20` function is implemented to address this problem. +1. While it is possible to implement a service that converts any token standard to any other standard - it is better to keep different standard convertors separate from one another as different standards may contain specific logic and therefore require different conversion approach. This proposal focuses on [ERC-20](./eip-20.md) and [ERC-223](./eip-223.md) upgradeability. +2. [ERC-20](./eip-20.md) tokens can be deposited to any contract directly with `transfer` function. This may result in a permanent loss of tokens because it is not possible to recognize this transaction on the recipients side. Therefore wrapper-ERC-20 tokens are prone to this problem as they are compatible with the [ERC-20](./eip-20.md) standard. `rescueERC20` function is implemented to address this problem. 3. Token Converter relies on [ERC-20](./eip-20.md) `approve` & `transferFrom` method of depositing assets. Any related issues must be taken into account. `approve` and `transferFrom` are two separate transactions so it is required to make sure `approval` was successful before relying on `transferFrom`. -4. This is a common practice for UI services to prompt a user to issue unlimited `approval` on any contract that may withdraw tokens from the user. This puts users funds at high risk and therefore not recommended. -5. It is possible to artificially construct a token that will pretend it is a [ERC-20](./eip-20.md) token that implements `approve & transferFrom` but at the same time implements [ERC-223](./eip-223.md) logic of transferring via `transfer` function in its internal logic. It can be possible to create a [ERC-223](./eip-223.md) wrapper for this [ERC-20](./eip-20.md)-[ERC-223](./eip-223.md) hybrid implementation in the Token Converter. This doesn't pose any threat for the workflow of the Token Converter but it must be taken into account that if a token has [ERC-223](./eip-223.md) wrapper in the Token Converter it does not automatically mean the origin is fully compatible with the [ERC-20](./eip-20.md) standard and methods of introspection must be used to determine the origins compatibility with any existing standard. +4. This is a common practice for UI services to prompt a user to issue unlimited `approval` on any contract that may withdraw tokens from the user. This puts users funds at risk and therefore is not recommended. +5. There is no reliable token standard introspection method available that could guarantee that a token implements a particular token standard. It is possible to artificially construct a token that will pretend it is a [ERC-20](./eip-20.md) token that implements `approve & transferFrom` but at the same time implements [ERC-223](./eip-223.md) logic of transferring via `transfer` function. It can be possible to create a [ERC-223](./eip-223.md) wrapper for this [ERC-20](./eip-20.md)-[ERC-223](./eip-223.md) hybrid implementation in the Token Converter. This doesn't pose any threat for the workflow of the Token Converter itself but it must be taken into account that if a token has [ERC-223](./eip-223.md) wrapper in the Token Converter it does not automatically mean the origin is fully compatible with the [ERC-20](./eip-20.md) standard and methods of introspection must be used to determine the origins compatibility with any existing standard. +6. Token Converter does not verify the standard of a provided token when it is asked to create a wrapper for it due to the lack of reliable standard introspection method. It is possible to call `createERC20Wrapper` function and provide an address of an existing [ERC-20](./eip-20.md) token. The Token Converter will successfully create a [ERC-20](./eip-20.md) wrapper for that [ERC-20](./eip-20.md) original token. It is also possible to create a [ERC-223](./eip-223.md) wrapper for that exact original [ERC-20](./eip-20.md) token. This doesn't pose any threat to the workflow of the Converter but it must be taken into account that any token regardless of it's original standard may have up to two wrappers created by the Converter, one for each standard. Any wrapper token must have exactly one origin. It is not possible to create a wrapper for a wrapper. +7. The Token Converter only holds the original tokens that were deposited during the conversion process and it assumes that tokens do not decay over time and the token balance of the Converter does not decrease on its own. If some token implements burning logic or decaying supply and it may impact the balance of the Converter then the Converter must not be used to deploy an alternative version of that token as it will not be able to guarantee that there is enough tokens for the conversion at any time. ## Copyright From eeeeb5f7f1d5d09e31dea16e3870d078b13e2ccf Mon Sep 17 00:00:00 2001 From: Daniel Gretzke Date: Sun, 29 Sep 2024 03:38:51 +0200 Subject: [PATCH 10/46] Add ERC: Wrapping of bubbled up reverts Merged by EIP-Bot. --- ERCS/erc-7751.md | 143 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 ERCS/erc-7751.md diff --git a/ERCS/erc-7751.md b/ERCS/erc-7751.md new file mode 100644 index 0000000000..ac91a16651 --- /dev/null +++ b/ERCS/erc-7751.md @@ -0,0 +1,143 @@ +--- +eip: 7751 +title: Wrapping of bubbled up reverts +description: Handling bubbled up reverts using custom errors with additional context +author: Daniel Gretzke (@gretzke), Sara Reynolds (@snreynolds), Alice Henshaw (@hensha256), Marko Veniger , Hadrien Croubois (@Amxx) +discussions-to: https://ethereum-magicians.org/t/erc-7751-wrapping-of-bubbled-up-reverts/20740 +status: Draft +type: Standards Track +category: ERC +created: 2024-08-06 +--- + +## Abstract + +This ERC proposes a standard for handling bubbled up reverts in Ethereum smart contracts using custom errors. This standard aims to improve the clarity and usability of revert reasons by allowing additional context to be passed alongside the raw bytes of the bubbled up revert. The custom errors should follow the naming structure `Wrap__` followed by a descriptive name and allow an arbitrary number of parameters, with the first being the address of the called contract and the second being the raw bytes of the bubbled up revert. + +## Motivation + +Currently, when a smart contract calls another and the called contract reverts, the revert reason is usually bubbled up and thrown as is. This can make it more difficult to tell which context the error came from. By standardizing the use of custom errors with additional context, more meaningful and informative revert reasons can be provided. This will improve the debugging experience and make it easier for developers and infrastructure providers like Etherscan to display accurate stack traces. + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +1. **Custom Error Naming Convention:** + - Custom errors that bubble up reverts MUST be prefixed with `Wrap__`. + - Example: `Wrap__ERC20TransferFailed`. +2. **Parameters:** + - The first parameter MUST be the address of the called contract that reverted. + - The second parameter MUST be the raw bytes of the bubbled up revert. + - Additional parameters MAY be included to provide context. + - Example: `Wrap__ERC20TransferFailed(address token, bytes reason, address recipient)`. + +If no additional parameters are defined and a generic call reverts, the custom error `Wrap__SubcontextReverted(address, bytes)` SHOULD be thrown to ensure a consistent signature. + +## Rationale + +By including the called contract, raw revert bytes and additional context, developers can provide more detailed information about the failure. Additionally, by standardizing the way reverts are bubbled up, it also enables nested bubbled up reverts where multiple reverts thrown by different contracts can be followed recursively. The reverts can also be parsed and handled by tools like Etherscan and Foundry to further enhance the readability and debuggability of smart contract interactions, as well as facilitating better error handling practices in general. + +## Backwards Compatibility + +This ERC does not introduce any backwards incompatibilities. Existing contracts can adopt this standard incrementally. + +## Test Cases + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +contract Token { + mapping(address => uint256) public balanceOf; + + event Transfer(address indexed sender, address indexed recipient, uint amount); + + function transfer(address to, uint256 amount) external returns (bool) { + require(balanceOf[msg.sender] >= amount, "insufficient balance"); + balanceOf[msg.sender] -= amount; + balanceOf[to] += amount; + emit Transfer(msg.sender, to, amount); + return true; + } +} + +contract Vault { + Token token; + + error Wrap__ERC20TransferFailed(address token, bytes reason, address recipient); + + constructor(Token token_) { + token = token_; + } + + function withdraw(address to, uint256 amount) external { + // logic + try token.transfer(to, amount) {} catch (bytes memory error) { + revert Wrap__ERC20TransferFailed(address(token), error, to); + } + } +} + +contract Router { + Vault vault; + + error Wrap__SubcontextReverted(address target, bytes reason); + + constructor(Vault vault_) { + vault = vault_; + } + + function withdraw(uint256 amount) external { + // logic + try vault.withdraw(msg.sender, amount) {} catch (bytes memory error) { + revert Wrap__SubcontextReverted(address(vault), error); + } + } +} + +contract Test { + function test_BubbledNestedReverts(uint256 amount) external { + Token token = new Token(); + Vault vault = new Vault(token); + Router router = new Router(vault); + + try router.withdraw(amount) {} catch (bytes memory thrownError) { + bytes memory expectedError = abi.encodeWithSelector( + Router.Wrap__SubcontextReverted.selector, address(vault), abi.encodeWithSelector( + Vault.Wrap__ERC20TransferFailed.selector, + address(token), + abi.encodeWithSignature("Error(string)", "insufficient balance"), + address(this) + ) + ); + assert(keccak256(thrownError) == keccak256(expectedError)); + } + } +} +``` + +## Reference Implementation + +When catching a revert from a called contract, the calling contract should revert with a custom error following the above conventions. + +```solidity +contract Foo { + error Wrap__SubcontextReverted(address target, bytes reason); + + function foo(address to, bytes memory data) external { + // logic + (bool success, bytes memory returnData) = to.call(data); + if (!success) { + revert Wrap__SubcontextReverted(to, returnData); + } + } +} +``` + +## Security Considerations + +This EIP does not introduce new security risks. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From 3cd06e80e25b968ef03248fbf56f090a726c7dc2 Mon Sep 17 00:00:00 2001 From: "drCathieSo.eth" Date: Tue, 1 Oct 2024 22:04:55 +0800 Subject: [PATCH 11/46] Update ERC-7007: Move to Final Merged by EIP-Bot. --- ERCS/erc-7007.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ERCS/erc-7007.md b/ERCS/erc-7007.md index caac5be17b..ddf6a83c22 100644 --- a/ERCS/erc-7007.md +++ b/ERCS/erc-7007.md @@ -4,8 +4,7 @@ title: Verifiable AI-Generated Content Token description: An ERC-721 extension for verifiable AI-generated content tokens using Zero-Knowledge and Optimistic Machine Learning techniques author: Cathie So (@socathie), Xiaohang Yu (@xhyumiracle), Conway (@0x1cc), Lee Ting Ting (@tina1998612), Kartin discussions-to: https://ethereum-magicians.org/t/eip-7007-zkml-aigc-nfts-an-erc-721-extension-interface-for-zkml-based-aigc-nfts/14216 -status: Last Call -last-call-deadline: 2024-09-30 +status: Final type: Standards Track category: ERC created: 2023-05-10 @@ -233,4 +232,4 @@ In the opML scenario, it is important to consider that the `aigcData` might chan ## Copyright -Copyright and related rights waived via [CC0](../LICENSE.md). \ No newline at end of file +Copyright and related rights waived via [CC0](../LICENSE.md). From b3be3b6f3536dd0c0bf0932de2ea4655c0fcb762 Mon Sep 17 00:00:00 2001 From: Andreas Freund Date: Tue, 1 Oct 2024 07:06:44 -0700 Subject: [PATCH 12/46] Update ERC-6734: Move to Review (#601) * Move ERC 6734 to Status: Review * Updates based on feedbacl Removed mention of EIP-3220 * updated requires section to remove 3220 --- ERCS/erc-6734.md | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/ERCS/erc-6734.md b/ERCS/erc-6734.md index bacfe8f19e..f22df1b8fe 100644 --- a/ERCS/erc-6734.md +++ b/ERCS/erc-6734.md @@ -4,11 +4,11 @@ title: L2 Token List description: Token List that ensures the correct identification of tokens from different Layer 1, Layer 2, or Sidechains. author: Kelvin Fichter (@smartcontracts), Andreas Freund (@Therecanbeonlyone1969), Pavel Sinelnikov (@psinelnikov) discussions-to: https://ethereum-magicians.org/t/canonical-token-list-standard-from-the-eea-oasis-community-projects-l2-standards-working-group/13091 -status: Draft +status: Review type: Standards Track category: ERC created: 2023-03-20 -requires: 155, 3220 +requires: 155 --- ## Abstract @@ -133,12 +133,7 @@ The chainId property utilized MUST allow for the requirements of the [EIP-155](. Namely, transaction replay protection on the network that is identified by the chainId property value. Note, that for replay protection to be guaranteed, the chainId should be unique. Ensuring a unique chainId is beyond the scope of this document. -[[R4]](#r4) testability: EIP-155 requires that a transaction hash is derived from the keccak256 hash of the following nine RLP encoded elements `(nonce, gasprice, startgas, to, value, data, chainid, 0, 0)` which can be tested easily with existing cryptographic libraries. EIP-155 further requires that the `v` value of the secp256k1 signature must be set to `{0,1} + CHAIN_ID * 2 + 35` where `{0,1}` is the parity of the `y` value of the curve point for which the signature `r`-value is the `x`-value in the secp256k1 signing process. This requirement is testable with available open-source secp256k1 digital signature suites. Therefore, [[R4]](#r4) is testable. - - **[D2]** -The `chainId` property SHOULD follow [EIP-3220](./eip-3220.md) draft standard. - -[[D2]](#d2) testability: The [EIP-3220](./eip-3220.md) draft standard can be tested because the crosschain id is specified as a concatenation of well-defined strings, and using open source tooling can be used to parse and split a crosschain id, the obtained string segments can be compared against expected string lengths, and context dependent, the values for the strings specified in the standard. Consequently, [[D2]](#d2) is testable. +[[R4]](#r4) testability: EIP-155 requires that a transaction hash is derived from the keccak256 hash of the following nine RLP encoded elements `(nonce, gasprice, startgas, to, value, data, chainid, 0, 0)` which can be tested easily with existing cryptographic libraries. EIP-155 further requires that the `v` value of the secp256k1 signature must be set to `{0,1} + CHAIN_ID * 2 + 35` where `{0,1}` is the parity of the `y` value of the curve point for which the signature `r`-value is the `x`-value in the secp256k1 signing process. This requirement is testable with available open-source secp256k1 digital signature suites. Therefore, [[R4]](#r4) is testable. **[O1]** The `humanReadableTokenSymbol` property MAY be used. @@ -491,10 +486,10 @@ This document defines the conformance levels of a canonical token list as follow * **Level 2:** All MUST and SHOULD requirements are fulfilled by a specific implementation as proven by a test report that proves in an easily understandable manner the implementation's conformance with each requirement based on implementation-specific test-fixtures with implementation-specific test-fixture inputs. * **Level 3:** All MUST, SHOULD, and MAY requirements with conditional MUST or SHOULD requirements are fulfilled by a specific implementation as proven by a test report that proves in an easily understandable manner the implementation's conformance with each requirement based on implementation-specific test-fixtures with implementation-specific test-fixture inputs. - **[D3]** + **[D2]** A claim that a canonical token list implementation conforms to this specification SHOULD describe a testing procedure carried out for each requirement to which conformance is claimed, that justifies the claim with respect to that requirement. -[[D3]](#d3) testability: Since each of the non-conformance-target requirements in this documents is testable, so must be the totality of the requirements in this document. Therefore, conformance tests for all requirements can exist, and can be described as required in [[D3]](#d3). +[[D2]](#d2) testability: Since each of the non-conformance-target requirements in this documents is testable, so must be the totality of the requirements in this document. Therefore, conformance tests for all requirements can exist, and can be described as required in [[D2]](#d2). **[R5]** A claim that a canonical token list implementation conforms to this specification at **Level 2** or higher MUST describe the testing procedure carried out for each requirement at **Level 2** or higher, that justifies the claim to that requirement. From 33ff9823e15cb81a0e0880b7d36b7d4fbafa73b9 Mon Sep 17 00:00:00 2001 From: Riley Date: Tue, 1 Oct 2024 10:14:48 -0400 Subject: [PATCH 13/46] Update ERC-6909: Move to Review Merged by EIP-Bot. --- ERCS/erc-6909.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-6909.md b/ERCS/erc-6909.md index ea343004ee..63d566397f 100644 --- a/ERCS/erc-6909.md +++ b/ERCS/erc-6909.md @@ -4,7 +4,7 @@ title: Minimal Multi-Token Interface description: A minimal specification for managing multiple tokens by their id in a single contract. author: JT Riley (@jtriley-eth), Dillon (@d1ll0n), Sara (@snreynolds), Vectorized (@Vectorized), Neodaoist (@neodaoist) discussions-to: https://ethereum-magicians.org/t/eip-6909-multi-token-standard/13891 -status: Draft +status: Review type: Standards Track category: ERC created: 2023-04-19 From a9ea794a79e1852b7b5d847b44b694cd5a99270e Mon Sep 17 00:00:00 2001 From: Daniel Gretzke Date: Fri, 4 Oct 2024 00:22:49 +0200 Subject: [PATCH 14/46] Update ERC-7751: Update custom error and add security considerations Merged by EIP-Bot. --- ERCS/erc-7751.md | 51 +++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/ERCS/erc-7751.md b/ERCS/erc-7751.md index ac91a16651..d12ad7670e 100644 --- a/ERCS/erc-7751.md +++ b/ERCS/erc-7751.md @@ -12,7 +12,7 @@ created: 2024-08-06 ## Abstract -This ERC proposes a standard for handling bubbled up reverts in Ethereum smart contracts using custom errors. This standard aims to improve the clarity and usability of revert reasons by allowing additional context to be passed alongside the raw bytes of the bubbled up revert. The custom errors should follow the naming structure `Wrap__` followed by a descriptive name and allow an arbitrary number of parameters, with the first being the address of the called contract and the second being the raw bytes of the bubbled up revert. +This ERC proposes a standard for handling bubbled up reverts in Ethereum smart contracts using a dedicated custom error. This standard aims to improve the clarity and usability of revert reasons by allowing additional context to be passed alongside the raw bytes of the bubbled up revert. The `WrappedError` custom error should wrap reverts from called contracts and provide a consistent interface for parsing and handling reverts in tools like Etherscan or Tenderly. ## Motivation @@ -22,20 +22,22 @@ Currently, when a smart contract calls another and the called contract reverts, The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. -1. **Custom Error Naming Convention:** - - Custom errors that bubble up reverts MUST be prefixed with `Wrap__`. - - Example: `Wrap__ERC20TransferFailed`. -2. **Parameters:** - - The first parameter MUST be the address of the called contract that reverted. - - The second parameter MUST be the raw bytes of the bubbled up revert. - - Additional parameters MAY be included to provide context. - - Example: `Wrap__ERC20TransferFailed(address token, bytes reason, address recipient)`. +In order to wrap a revert, a contract MUST revert with the following error that corresponds to the following signature `0x90bfb865`: -If no additional parameters are defined and a generic call reverts, the custom error `Wrap__SubcontextReverted(address, bytes)` SHOULD be thrown to ensure a consistent signature. +```solidity +error WrappedError(address target, bytes4 selector, bytes reason, bytes details); +``` + +Where: + +- `target` is the address of the called contract that reverted. +- `selector` is the selector of the called function that reverted. If the call was an ETH transfer without any data, the selector MUST be `bytes4(0)` +- `reason` is the raw bytes of the revert reason. +- `details` is optional additional context about the revert. In cases where no additional context is needed, the `details` bytes can be empty. In cases with additional context, the `details` bytes MUST be an ABI encoded custom error declared on the contract that emits the `WrappedError` error. ## Rationale -By including the called contract, raw revert bytes and additional context, developers can provide more detailed information about the failure. Additionally, by standardizing the way reverts are bubbled up, it also enables nested bubbled up reverts where multiple reverts thrown by different contracts can be followed recursively. The reverts can also be parsed and handled by tools like Etherscan and Foundry to further enhance the readability and debuggability of smart contract interactions, as well as facilitating better error handling practices in general. +By including the called contract and function, raw revert bytes and additional context, developers can provide more detailed information about the failure. Additionally, by standardizing the way reverts are bubbled up, it also enables nested bubbled up reverts where multiple reverts thrown by different contracts can be followed recursively. The reverts can also be parsed and handled by tools like Etherscan and Foundry to further enhance the readability and debuggability of smart contract interactions, as well as facilitating better error handling practices in general. ## Backwards Compatibility @@ -64,7 +66,9 @@ contract Token { contract Vault { Token token; - error Wrap__ERC20TransferFailed(address token, bytes reason, address recipient); + error WrappedError(address target, bytes4 selector, bytes reason, bytes details); + error ERC20TransferFailed(address recipient); + constructor(Token token_) { token = token_; @@ -73,7 +77,7 @@ contract Vault { function withdraw(address to, uint256 amount) external { // logic try token.transfer(to, amount) {} catch (bytes memory error) { - revert Wrap__ERC20TransferFailed(address(token), error, to); + revert WrappedError(address(token), token.transfer.selector, error, abi.encodeWithSelector(ERC20TransferFailed.selector, to)); } } } @@ -81,7 +85,7 @@ contract Vault { contract Router { Vault vault; - error Wrap__SubcontextReverted(address target, bytes reason); + error WrappedError(address target, bytes4 selector, bytes reason, bytes details); constructor(Vault vault_) { vault = vault_; @@ -90,7 +94,7 @@ contract Router { function withdraw(uint256 amount) external { // logic try vault.withdraw(msg.sender, amount) {} catch (bytes memory error) { - revert Wrap__SubcontextReverted(address(vault), error); + revert WrappedError(address(vault), vault.withdraw.selector, error, ""); } } } @@ -103,12 +107,13 @@ contract Test { try router.withdraw(amount) {} catch (bytes memory thrownError) { bytes memory expectedError = abi.encodeWithSelector( - Router.Wrap__SubcontextReverted.selector, address(vault), abi.encodeWithSelector( - Vault.Wrap__ERC20TransferFailed.selector, + Router.WrappedError.selector, address(vault), vault.withdraw.selector, abi.encodeWithSelector( + Vault.WrappedError.selector, address(token), + token.transfer.selector, abi.encodeWithSignature("Error(string)", "insufficient balance"), - address(this) - ) + abi.encodeWithSelector(Vault.ERC20TransferFailed.selector, address(this)) + ), "" ); assert(keccak256(thrownError) == keccak256(expectedError)); } @@ -122,13 +127,15 @@ When catching a revert from a called contract, the calling contract should rever ```solidity contract Foo { - error Wrap__SubcontextReverted(address target, bytes reason); + + error WrappedError(address target, bytes4 selector, bytes reason, bytes details); + error MyCustomError(uint256 x); function foo(address to, bytes memory data) external { // logic (bool success, bytes memory returnData) = to.call(data); if (!success) { - revert Wrap__SubcontextReverted(to, returnData); + revert WrappedError(to, bytes4(data), returnData, abi.encodeWithSelector(MyCustomError.selector, 42)); } } } @@ -136,7 +143,7 @@ contract Foo { ## Security Considerations -This EIP does not introduce new security risks. +Smart contracts could either drop or purposefully suppress the bubbled up reverts along the revert chain. Additionally, smart contracts may also lie or incorrectly report the wrapped reverts, so the information is not guaranteed to be accurate. ## Copyright From 610506a71c36bed49dde9339d5c77e884df4ddbc Mon Sep 17 00:00:00 2001 From: filmakarov Date: Fri, 4 Oct 2024 18:09:00 +0300 Subject: [PATCH 15/46] Update ERC-7579: executeUserOp + multitype module onInstall/onUninstall Merged by EIP-Bot. --- ERCS/erc-7579.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/ERCS/erc-7579.md b/ERCS/erc-7579.md index 2f3542e23c..8730fe2276 100644 --- a/ERCS/erc-7579.md +++ b/ERCS/erc-7579.md @@ -91,6 +91,13 @@ The account MAY also implement the following function in accordance with ERC-433 function executeUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash) external; ``` +If an account chooses to implement `executeUserOp`, this method SHOULD ensure the account executes `userOp.calldata` except 4 most significant bytes, which are reserved for `executeUserOp.selector` as per ERC-4337. Thus the `userOp.callData[4:]` should represent the calldata for a valid call to the account. It is RECOMMENDED that the account executes a `delegatecall` in order to preserve the original `msg.sender` to the account. + +Example: +``` +(bool success, bytes memory innerCallRet) = address(this).delegatecall(userOp.callData[4:]); +``` + The execution mode is a `bytes32` value that is structured as follows: - callType (1 byte): `0x00` for a single `call`, `0x01` for a batch `call`, `0xfe` for `staticcall` and `0xff` for `delegatecall` @@ -223,6 +230,9 @@ If the smart account has a fallback handler installed, it: - MUST route to fallback handlers based on the function selector of the calldata - MAY implement authorization control, which SHOULD be done via hooks +If the account adds features via fallback, these should be considered the same as if the account was implementing those features natively. +ERC-165 support (see below) is one example of such an approach. Note, that it is only RECOMMENDED to implement view functions via fallback where this can lead to greater extensibility. It is NOT RECOMMENDED to implement core account logic via a fallback. + #### ERC-165 Smart accounts MUST implement ERC-165. However, for every interface function that reverts instead of implementing the functionality, the smart account MUST return `false` for the corresponding interface id. @@ -268,6 +278,17 @@ interface IModule { } ``` +Note: A single module that is of multiple types MAY decide to pass `moduleTypeId` inside `data` to `onInstall` and/or `onUninstall` methods, so those methods are able to properly handle installation/uninstallation for various types. +Example: +```solidity +// Module.sol +function onInstall(bytes calldata data) external { + // ... + (uint256 moduleTypeId, bytes memory otherData) = abi.decode(data, (uint256, bytes)); + // ... +} +``` + #### Validators Validators MUST implement the `IModule` and the `IValidator` interface and have module type id: `1`. From 1526cbae597a40a9192f14c35c907811b91a5bf1 Mon Sep 17 00:00:00 2001 From: Vidor <1101164+V1d0r@users.noreply.github.com> Date: Tue, 8 Oct 2024 09:32:53 +0100 Subject: [PATCH 16/46] Update ERC-7578: Update getter and setter methods naming Merged by EIP-Bot. --- ERCS/erc-7578.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ERCS/erc-7578.md b/ERCS/erc-7578.md index 9acb4fbb37..b4a237483f 100644 --- a/ERCS/erc-7578.md +++ b/ERCS/erc-7578.md @@ -104,7 +104,7 @@ interface IERC7578 { * @dev Does NOT revert if token doesn't exist * @param tokenId The token ID of the minted token */ - function getProperties(uint256 tokenId) external view returns (Properties memory properties); + function getPropertiesOf(uint256 tokenId) external view returns (Properties memory properties); } ``` @@ -112,7 +112,7 @@ When `properties` are set, the `PropertiesSet(uint256 indexed tokenId, Propertie When `properties` are removed, the `PropertiesRemoved(uint256 indexed tokenId)` event is emitted. -The `getProperties(uint256 tokenId)` function MUST return the unique `properties` of a token. If the ERC-721 token is burned or has no properties set, it SHOULD return an empty `Properties` struct. +The `getPropertiesOf(uint256 tokenId)` function MUST return the unique `properties` of a token. If the ERC-721 token is burned or has no properties set, it SHOULD return an empty `Properties` struct. ## Rationale @@ -158,7 +158,7 @@ contract ERC7578 is ERC721, IERC7578 { /** * @inheritdoc IERC7578 */ - function getProperties(uint256 tokenId) public view override returns (Properties memory properties) { + function getPropertiesOf(uint256 tokenId) public view override returns (Properties memory properties) { properties = _properties[tokenId]; } @@ -172,7 +172,7 @@ contract ERC7578 is ERC721, IERC7578 { * * Emits a {PropertiesSet} event */ - function _setProperties(uint256 tokenId, Properties calldata properties) internal { + function _setPropertiesOf(uint256 tokenId, Properties calldata properties) internal { _properties[tokenId] = Properties({ tokenIssuer: properties.tokenIssuer, assetHolder: properties.assetHolder, @@ -194,7 +194,7 @@ contract ERC7578 is ERC721, IERC7578 { * * Emits a {PropertiesRemoved} event */ - function _removeProperties(uint256 tokenId) internal { + function _removePropertiesOf(uint256 tokenId) internal { delete _properties[tokenId]; emit PropertiesRemoved(tokenId); } @@ -207,7 +207,7 @@ contract ERC7578 is ERC721, IERC7578 { function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address) { address from = _ownerOf(tokenId); if (to == address(0)) { - _removeProperties(tokenId); + _removePropertiesOf(tokenId); } else if (from == address(0)) { if (bytes(_properties[tokenId].tokenIssuer).length == 0) revert PropertiesUninitialized(); } @@ -219,7 +219,7 @@ contract ERC7578 is ERC721, IERC7578 { ## Security Considerations -To ensure the authenticity of a token's properties, the `_setProperties()` method should only be called inside a method that is restricted to a trusted Externally Owned Account (EOA) or contract. This trusted entity must verify that the properties accurately reflect the real physical attributes of the token. +To ensure the authenticity of a token's properties, the `_setPropertiesOf()` method should only be called inside a method that is restricted to a trusted Externally Owned Account (EOA) or contract. This trusted entity must verify that the properties accurately reflect the real physical attributes of the token. ## Copyright From 3173a488e7d4da604ae137d38ab3bbfd9ee4064a Mon Sep 17 00:00:00 2001 From: sshmatrix Date: Fri, 11 Oct 2024 22:50:40 +0530 Subject: [PATCH 17/46] Make ERC-7700 Image Optimsations Merged by EIP-Bot. --- assets/erc-7700/fonts/Licenses/Rajdhani.txt | 93 + assets/erc-7700/fonts/Rajdhani.woff2 | 2365 +++++++++++++++++++ assets/erc-7700/images/Database.svg | 291 ++- assets/erc-7700/images/Keygen.svg | 710 +++--- assets/erc-7700/images/L1.svg | 288 +-- assets/erc-7700/images/L2.svg | 188 +- assets/erc-7700/images/Schema.svg | 1736 +++++++------- 7 files changed, 4093 insertions(+), 1578 deletions(-) create mode 100644 assets/erc-7700/fonts/Licenses/Rajdhani.txt create mode 100644 assets/erc-7700/fonts/Rajdhani.woff2 diff --git a/assets/erc-7700/fonts/Licenses/Rajdhani.txt b/assets/erc-7700/fonts/Licenses/Rajdhani.txt new file mode 100644 index 0000000000..fa88d37258 --- /dev/null +++ b/assets/erc-7700/fonts/Licenses/Rajdhani.txt @@ -0,0 +1,93 @@ +Copyright (c) 2009, Indian Type Foundry + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. \ No newline at end of file diff --git a/assets/erc-7700/fonts/Rajdhani.woff2 b/assets/erc-7700/fonts/Rajdhani.woff2 new file mode 100644 index 0000000000..5545c74460 --- /dev/null +++ b/assets/erc-7700/fonts/Rajdhani.woff2 @@ -0,0 +1,2365 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ERCs/assets/erc-7694/fonts/Rajdhani.woff2 at solanaHandler · namesys-eth/ERCs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ Skip to content + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+ + + + + +
+ + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + +
+ Open in github.dev + Open in a new github.dev tab + Open in codespace + + + + + + + + + + + + + + + + + + +

Latest commit

 

History

History
99.4 KB

Rajdhani.woff2

File metadata and controls

99.4 KB
+
+ + + + +
+ +
+ +
+
+ +
+ +
+

Footer

+ + + + +
+
+ + + + + © 2024 GitHub, Inc. + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + diff --git a/assets/erc-7700/images/Database.svg b/assets/erc-7700/images/Database.svg index 0da7511326..ee11cff923 100644 --- a/assets/erc-7700/images/Database.svg +++ b/assets/erc-7700/images/Database.svg @@ -8,14 +8,14 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="538.99292mm" - height="246.26625mm" - viewBox="0 0 538.99292 246.26626" + width="539.02795mm" + height="246.15076mm" + viewBox="0 0 539.02795 246.15077" version="1.1" id="svg6" inkscape:version="1.0.2 (e86c8708, 2021-01-15)" sodipodi:docname="Database.svg" - inkscape:export-filename="/Users/sshmatrix/Idee/sshmatrix/Buidl/namesys-eth/namesys-ccip-write/images/keygen.png" + inkscape:export-filename="Database.png" inkscape:export-xdpi="200" inkscape:export-ydpi="200"> + @@ -206,132 +216,105 @@ inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" - transform="translate(-33.411763,-64.921999)"> - - HTTP POST [ + + HTTP POST [signer] [signature] [approval] - [[callData] - - - setValue(calldata) - - - - L1 - - - - DB - + + L1 + + DB CONTRACT 1 + x="452.81824" + y="91.454376" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-width:0.325693;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">CONTRACT 1 revert StorageRoutedToDatabase(gatewayURL) + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-width:0.257131;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">revert StorageRoutedToDatabase[gatewayURL] response + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-width:0.257131;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">response - - - + CLIENT - + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.771;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;">CLIENT DATABASE + x="530.03149" + y="91.454376" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-width:0.325693;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">DATABASE + + setValue[calldata] + diff --git a/assets/erc-7700/images/Keygen.svg b/assets/erc-7700/images/Keygen.svg index 232ab77238..ae3da761be 100644 --- a/assets/erc-7700/images/Keygen.svg +++ b/assets/erc-7700/images/Keygen.svg @@ -8,14 +8,14 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="354.92731mm" - height="284.96518mm" - viewBox="0 0 354.92731 284.96518" + width="355.14566mm" + height="284.86801mm" + viewBox="0 0 355.14566 284.86801" version="1.1" id="svg6" inkscape:version="1.0.2 (e86c8708, 2021-01-15)" sodipodi:docname="Keygen.svg" - inkscape:export-filename="/Users/sshmatrix/Idee/sshmatrix/Buidl/namesys-eth/namesys-ccip-write/images/keygen.png" + inkscape:export-filename="Keygen.png" inkscape:export-xdpi="200" inkscape:export-ydpi="200"> + @@ -200,7 +210,14 @@ inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" - transform="translate(-26.391586,-23.472401)"> + transform="translate(-26.319521,-23.400335)"> + keypairdecode + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:start;text-anchor:start;stroke:#ff4f00;stroke-width:0.502;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="301.8284" + y="147.56477" + id="tspan1159">KEYPAIR CAIP-10 + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.624383;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="-175.52129" + y="108.35208" + id="tspan2163-0-2-6-4-3-7">CAIP-10 pubkey PUBKEY[address] + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:start;text-anchor:start;stroke:#ff5500;stroke-width:0.429033;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="-165.38974" + y="99.295135" + id="tspan2447">[ADDRESS] MESSAGE signature + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.438444;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="191.58209" + y="254.40422" + id="tspan2163-0-2-6-4-3-2">SIGNATURE salt + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.345378;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="241.88663" + y="227.65532" + id="tspan2163-0-2-6-4-3-2-2">SALT wallet WALLETkeypair + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:start;text-anchor:start;fill:#0079ff;fill-opacity:1;stroke:#0079ff;stroke-width:0.433269;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="71.353035" + y="104.03593" + id="tspan1102">KEYPAIR inputINPUT key + style="font-size:4.95802px;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.337097;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="tspan3283"> KEY hashkey + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.359125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="282.19537" + y="154.02812" + id="tspan2163-0-2-6-4-3-2-2-0">HASHKEY - - - - USERNAME - - + + USERNAME - - - - password - - + + PASSWORD @@ -716,58 +705,52 @@ id="path1062-2-9-3-6" sodipodi:nodetypes="cccc" /> signerSIGNERkeys - - - CAIP-02 - + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ff4f00;fill-opacity:1;stroke:#ff4f00;stroke-width:0.516629;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="366.21487" + y="134.32416" + id="tspan1153">KEYS + + CAIP-02 otherOTHERkeys + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.516629;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="366.21487" + y="175.10515" + id="tspan1149">KEYS @@ -918,22 +901,22 @@ transform="matrix(0.27231888,0,0,0.27231888,213.85157,218.02482)" /> hkdf + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.594683;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="351.99957" + y="270.04156" + id="tspan2163-0-2-6-4-3-6-1">HKDF @@ -967,46 +950,30 @@ style="fill:#8c8c8c;fill-opacity:1;stroke:#ffffff;stroke-opacity:1" /> - - sha-SHA-256 - 256 - sign + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.594683;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="350.82336" + y="285.1387" + id="tspan2163-0-2-6-4-3-6-1-7">SIGN @@ -1015,28 +982,28 @@ + transform="matrix(0.07723047,0,0,0.07723047,316.7695,193.49336)" + style="fill:#8c8c8c;fill-opacity:1;stroke:#ffffff;stroke-width:4.39179;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"> + style="fill:#8c8c8c;fill-opacity:1;stroke:#ffffff;stroke-width:18.1111;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"> + style="fill:#8c8c8c;fill-opacity:1;stroke:#ffffff;stroke-width:18.1111;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:#8c8c8c;fill-opacity:1;stroke:#ffffff;stroke-width:18.1111;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:#8c8c8c;fill-opacity:1;stroke:#ffffff;stroke-width:8.79949;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"> + style="fill:#8c8c8c;fill-opacity:1;stroke:#ffffff;stroke-width:8.79949;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - - - - PROTOCOL - - + + PROTOCOL - - PBKDfPBKDF2 - 2 - @@ -1191,29 +1130,25 @@ style="fill:#ff4f00;fill-opacity:1;stroke:#ff4f00;stroke-width:18.1111;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - - - spice - + + SPICE - - - - pepper - - + + PEPPER + DECODE diff --git a/assets/erc-7700/images/L1.svg b/assets/erc-7700/images/L1.svg index 5b96abeecd..8899f9aa57 100644 --- a/assets/erc-7700/images/L1.svg +++ b/assets/erc-7700/images/L1.svg @@ -8,14 +8,14 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="538.99292mm" - height="246.12524mm" - viewBox="0 0 538.99292 246.12525" + width="538.9527mm" + height="246.08514mm" + viewBox="0 0 538.9527 246.08515" version="1.1" id="svg6" inkscape:version="1.0.2 (e86c8708, 2021-01-15)" sodipodi:docname="L1.svg" - inkscape:export-filename="/Users/sshmatrix/Idee/sshmatrix/Buidl/namesys-eth/namesys-ccip-write/images/keygen.png" + inkscape:export-filename="L1.png" inkscape:export-xdpi="200" inkscape:export-ydpi="200"> + @@ -206,58 +216,72 @@ inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" - transform="translate(-33.411763,-65.062998)"> + transform="translate(-33.582213,-65.062996)"> + + + + + + Execute on Mainnet [Execute on Mainnet [contract] [callData] setValue(calldata) + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.26869px;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-width:0.309;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">setValue(calldata) - - @@ -268,74 +292,65 @@ sodipodi:nodetypes="ccccccccccc" /> L1 - - - - L1 + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-width:0.771;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">L1 + + style="font-size:12.8702px;line-height:1.25;font-family:Palatino;-inkscape-font-specification:Palatino;font-variant-ligatures:none;text-align:center;letter-spacing:0.264583px;text-anchor:middle;fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-width:0.771;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="513.16644" + y="112.60666" + id="text1098-9-0" + transform="scale(1.0134682,0.98671079)">L1 CONTRACT 1 + x="452.81824" + y="91.454376" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-width:0.325693;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">CONTRACT 1 CONTRACT 2 + x="527.39014" + y="91.454376" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-width:0.325693;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">CONTRACT 2 @@ -345,189 +360,190 @@ id="path1225-8" sodipodi:nodetypes="cc" /> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1" /> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1" /> - - revert revert StorageRoutedToL1(contract) - + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1" /> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> response + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-width:0.257131;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">response CLIENT + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.771;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">CLIENT + diff --git a/assets/erc-7700/images/L2.svg b/assets/erc-7700/images/L2.svg index 992e67b6a6..bc2e12bc71 100644 --- a/assets/erc-7700/images/L2.svg +++ b/assets/erc-7700/images/L2.svg @@ -8,14 +8,14 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="538.99292mm" - height="246.12524mm" - viewBox="0 0 538.99292 246.12525" + width="538.23016mm" + height="245.64159mm" + viewBox="0 0 538.23016 245.64159" version="1.1" id="svg6" inkscape:version="1.0.2 (e86c8708, 2021-01-15)" sodipodi:docname="L2.svg" - inkscape:export-filename="/Users/sshmatrix/Idee/sshmatrix/Buidl/namesys-eth/namesys-ccip-write/images/keygen.png" + inkscape:export-filename="L2.png" inkscape:export-xdpi="200" inkscape:export-ydpi="200"> + @@ -206,52 +216,57 @@ inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" - transform="translate(-33.411763,-65.062998)"> + transform="translate(-33.411762,-65.062996)"> + Execute on L2 [Execute on L2 [contract] [callData] setValue(calldata) + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.26869px;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-width:0.309;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">setValue[calldata] @@ -269,7 +284,7 @@ sodipodi:nodetypes="ccccccccccc" /> L1 + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-width:0.771;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;">L1 + style="fill:none;stroke:#ff5300;stroke-opacity:1"> L2 + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-width:0.771;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;">L2 CONTRACT 1 + x="452.81824" + y="91.454376" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-width:0.325693;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">CONTRACT 1 CONTRACT 2 + x="527.39014" + y="91.454376" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-width:0.325693;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">CONTRACT 2 @@ -346,169 +361,168 @@ id="path1225-8" sodipodi:nodetypes="cc" /> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1" /> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1" /> revert StorageRoutedToL2(chainId, contract) + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-width:0.257131;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">revert StorageRoutedToL2[chainId, contract] + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1" /> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> response + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-width:0.257131;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">response @@ -519,7 +533,7 @@ sodipodi:nodetypes="ccccccc" /> CLIENT + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.771;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;">CLIENT diff --git a/assets/erc-7700/images/Schema.svg b/assets/erc-7700/images/Schema.svg index e78b204601..5e54cf63a4 100644 --- a/assets/erc-7700/images/Schema.svg +++ b/assets/erc-7700/images/Schema.svg @@ -8,14 +8,14 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="420.71497mm" - height="251.75276mm" - viewBox="0 0 420.71498 251.75276" + width="420.40274mm" + height="251.61508mm" + viewBox="0 0 420.40275 251.61508" version="1.1" id="svg6" inkscape:version="1.0.2 (e86c8708, 2021-01-15)" sodipodi:docname="Schema.svg" - inkscape:export-filename="/Users/sshmatrix/Idee/sshmatrix/Buidl/namesys-eth/namesys-ccip-write/images/schematic.png" + inkscape:export-filename="Schema.png" inkscape:export-xdpi="200" inkscape:export-ydpi="200"> + @@ -258,21 +265,33 @@ id="layer1" transform="translate(-7.6321621,-18.227982)"> + + - ns1 - ns2 - ns3 - @@ -459,20 +432,6 @@ id="g1654-5" transform="matrix(0,-1,-1,0,416.6934,364.09144)" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - OffchainLookup(sender urls[] calldata callback() extradata ) - callback() - + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;stroke-width:0.264583" /> - extradata - - - - - - - - - Read - return - gateway - result - - - EIP-3668 - EIP-7700 - L2 - database - IPNS - ar - SOLANA - IPFS - IPNS - storage - ns1 - ns2 - ns3 + style="fill:#ffffff;fill-opacity:0.141129;stroke:#ffffff;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"> - L2 - IPFS - DATABASE - ARWEAVE - SOLANA - - - - + + - STORE - gateway - json-rpc - http - ipfs2 - ar-io - arns - arns @@ -1481,13 +818,795 @@
+ + + + EIP-7694 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OffchainLookup[sender urls[] calldata callback() extradata ] + callback[] + + extradata + + + + + + + + + READ + RETURN + GATEWAY + result + + + EIP-3668 + + L2 + DATABASE + SOLANA + STORAGE + NS1 + NS2 + NS3 + NS1 + NS2 + NS3 + IPNS + AR + IPFS + IPNS + ARNS + JSON-RPC + HTTP + API + JSON-RPC + IPFS2 + AR-IO + + + + + EIP-7694 + L 2 + DATABASE + SOLANA + STORE + GATEWAY + METADATA + IPFS + ARWEAVE + transform="translate(-12.561236,-26.217714)"> + transform="matrix(0.41454246,0,0,0.45705146,254.00403,204.65357)" + style="opacity:0.495177;fill:#ffffff;fill-opacity:1;stroke-width:0.999361;stroke-miterlimit:4;stroke-dasharray:none"> requires CID/keygen + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.01859px;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.334075;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="418.63412" + y="266.1683" + id="tspan2163-0-2-6-4-3-0-7-4-0-1-8-6-8-2">REQUIRES KEYGEN + style="opacity:0.495177;fill:#ffffff;fill-opacity:1;stroke-width:0.339802" /> requires signature + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.89777px;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.324031;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="374.89169" + y="257.35449" + id="tspan2163-0-2-6-4-3-0-7-4-0-1-8-6-8-2-2">REQUIRES SIGNATURE requires REQUIRES $ payment + dy="0.3754442">$ PAYMENT API - metadata - - - + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.50059px;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.46084;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="220.93579" + y="159.33699" + id="tspan2163-0-2-6-4-3-0-7-4-0-1-8-6-1-4-7-0-1-9">ARNS From 6493b550b77d1fbf32a54b2253c699a8ded75fdc Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Sun, 13 Oct 2024 16:12:16 -0400 Subject: [PATCH 18/46] Upgrade to eipw 0.9 (#672) --- .github/workflows/ci.yml | 2 +- config/eipw.toml | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4d00625581..fcf12c4d61 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -136,7 +136,7 @@ jobs: - name: Checkout EIP Repository uses: actions/checkout@47fbe2df0ad0e27efb67a70beac3555f192b062f - - uses: ethereum/eipw-action@6785fa283773db4819cb0abf17a185a1d9b6eb9f + - uses: ethereum/eipw-action@be3fa642ec311d0b8e1fdb811e5c9b4ada3d3d93 id: eipw with: token: ${{ secrets.GITHUB_TOKEN }} diff --git a/config/eipw.toml b/config/eipw.toml index c195734cd8..90322beaf0 100644 --- a/config/eipw.toml +++ b/config/eipw.toml @@ -2,13 +2,13 @@ kind = "set-default-annotation" name = "status" value = "Stagnant" -annotation_type = "warning" +annotation_level = "warning" [[modifiers]] kind = "set-default-annotation" name = "status" value = "Withdrawn" -annotation_type = "warning" +annotation_level = "warning" [lints.markdown-re-eip-dash] kind = "markdown-regex" @@ -115,6 +115,7 @@ names = [ # "Final", # "Withdrawn", # "Living", +# "Moved", # ], # ] @@ -145,6 +146,8 @@ exceptions = [ '^https://(www\.)?github\.com/ethereum/yellowpaper/commit/[a-f0-9]{40}$', '^https://(www\.)?github\.com/ethereum/devp2p/(blob|tree)/[0-9a-f]{40}/.+$', '^https://(www\.)?github\.com/ethereum/devp2p/commit/[0-9a-f]{40}$', + '^https://(www\.)?github\.com/ethereum/portal-network-specs/(blob|tree)/[0-9a-f]{40}/.+$', + '^https://(www\.)?github\.com/ethereum/portal-network-specs/commit/[0-9a-f]{40}$', '^https://(www\.)?github\.com/bitcoin/bips/(blob|tree)/[0-9a-f]{40}/bip-[0-9]+\.mediawiki$', '^https://(www\.)?github\.com/ChainAgnostic/CAIPs/(blob|tree)/[a-f0-9]{40}/.+$', '^https://(www\.)?github\.com/ChainAgnostic/CAIPs/commit/[0-9a-f]{40}$', @@ -794,6 +797,7 @@ flow = [ "Final", "Withdrawn", "Living", + "Moved", ], ] @@ -842,7 +846,7 @@ min = 1 [lints.markdown-link-first] kind = "markdown-link-first" -pattern = "(?i)(?:eip|erc)-[0-9]+" +pattern = "(?i)(?:eip|erc)-([0-9])+" [lints.markdown-re-erc-dash] kind = "markdown-regex" @@ -925,4 +929,9 @@ name = "eip" prefix = "erc-" suffix = ".md" +[lints.markdown-no-backticks] +kind = "markdown-no-backticks" +pattern = "(?i)(eip|erc)-[0-9]+" +[lints.markdown-headings-space] +kind = "markdown-headings-space" From 21416f5084e8059611e4d09b0717c78c72b50217 Mon Sep 17 00:00:00 2001 From: Vectorized Date: Mon, 14 Oct 2024 09:08:19 +0800 Subject: [PATCH 19/46] Add ERC: Readable Typed Signatures for Smart Accounts Merged by EIP-Bot. --- ERCS/erc-7739.md | 359 ++++++++++++++++++ .../erc-7739/contracts/accounts/ERC1271.sol | 320 ++++++++++++++++ assets/erc-7739/contracts/utils/EIP712.sol | 208 ++++++++++ assets/erc-7739/contracts/utils/LibString.sol | 171 +++++++++ .../contracts/utils/SignatureCheckerLib.sol | 114 ++++++ 5 files changed, 1172 insertions(+) create mode 100644 ERCS/erc-7739.md create mode 100644 assets/erc-7739/contracts/accounts/ERC1271.sol create mode 100644 assets/erc-7739/contracts/utils/EIP712.sol create mode 100644 assets/erc-7739/contracts/utils/LibString.sol create mode 100644 assets/erc-7739/contracts/utils/SignatureCheckerLib.sol diff --git a/ERCS/erc-7739.md b/ERCS/erc-7739.md new file mode 100644 index 0000000000..f4d4c86710 --- /dev/null +++ b/ERCS/erc-7739.md @@ -0,0 +1,359 @@ +--- +eip: 7739 +title: Readable Typed Signatures for Smart Accounts +description: A defensive rehashing scheme which prevents signature replays across smart accounts and preserves the readability of the signed contents +author: vectorized (@vectorized), Sihoon Lee (@push0ebp), Francisco Giordano (@frangio), Im Juno (@junomonster), howydev (@howydev), 0xcuriousapple (@0xcuriousapple) +discussions-to: https://ethereum-magicians.org/t/erc-7739-readable-typed-signatures-for-smart-accounts/20513 +status: Draft +type: Standards Track +category: ERC +created: 2024-05-28 +requires: 191, 712, 1271, 5267 +--- + +## Abstract + +This proposal defines a standard to prevent signature replays across multiple smart accounts when they are owned by a single Externally Owned Account (EOA). This is achieved through a defensive rehashing scheme for [ERC-1271](./eip-1271.md) verification using specific nested [EIP-712](./eip-712.md) typed structures, which preserves the readability of the signed contents during wallet client signature requests. + +## Motivation + +Smart accounts can verify signatures with via [ERC-1271](./eip-1271.md) using the `isValidSignature` function. + +A straightforward implementation as shown below, is vulnerable to signature replay attacks. + +```solidity +/// @dev This implementation is NOT safe. +function isValidSignature( + bytes32 hash, + bytes calldata signature +) external override view returns (bytes4) { + uint8 v = uint8(signature[64]); + (bytes32 r, bytes32 s) = abi.decode(signature, (bytes32, bytes32)); + // Reject malleable signatures. + require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0); + address signer = ecrecover(hash, v, r, s); + // Reject failed recovery. + require(signer != address(0)); + // `owner` is a storage variable containing the smart account's owner. + if (signer == owner) { + return 0x1626ba7e; + } else { + return 0xffffffff; + } +} +``` + +When multiple smart accounts are owned by a single EOA, the same signature can be replayed across the smart accounts if the `hash` does not include the smart account address. + +Unfortunately, this is the case for many popular applications (e.g. Permit2). As such, many smart account implementations perform some form of defensive rehashing. First, the smart account computes a final hash from minimally: (1) the hash, (2) its own address, (3) the chain ID. Then, the smart account verifies the final hash against the signature. Defensive rehashing can be implemented with [EIP-712](./eip-712.md), but a straightforward implementation will make the signed contents opaque. + +This standard provides a defensive rehashing scheme that makes the signed contents visible across all wallet clients that support [EIP-712](./eip-712.md). It is designed for minimal adoption friction. Even if wallet clients or application frontends are not updated, users can still inject client side JavaScript to enable the defensive rehashing. + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +### Overview + +Compliant smart accounts MUST implement the following dependencies: + +- [EIP-712](./eip-712.md) Typed structured data hashing and signing. + Provides the relevant typed data hashing logic internally, which is required to construct the final hashes. + +- [ERC-1271](./eip-1271.md) Standard Signature Validation Method for Contracts. + Provides the `isValidSignature(bytes32 hash, bytes calldata signature)` function. + +- [ERC-5267](./eip-5267.md) Retrieval of EIP-712 domain. + Provides the `eip712Domain()` function which is required to compute the final hashes. + +This standard defines the behavior of the `isValidSignature` function for [ERC-1271](./eip-1271.md), which comprises of two workflows: (1) the `TypedDataSign` workflow, (2) the `PersonalSign` workflow. + +### `TypedDataSign` workflow + +The `TypedDataSign` workflow handles the case where the `hash` is originally computed with [EIP-712](./eip-712.md). + +#### `TypedDataSign` final hash + +The final hash for the `TypedDataSign` workflow is defined as: + +``` +keccak256(\x19\x01 ‖ APP_DOMAIN_SEPARATOR ‖ + hashStruct(TypedDataSign({ + contents: hashStruct(originalStruct), + name: eip712Domain().name, + version: eip712Domain().version, + chainId: eip712Domain().chainId, + verifyingContract: eip712Domain().verifyingContract, + salt: eip712Domain().salt, + extensions: eip712Domain().extensions + })) +) +``` + +where `‖` denotes the concatenation operator for bytes. + +In Solidity, this can be written as: + +```solidity +finalTypedDataSignHash = + keccak256( + abi.encodePacked( + hex"1901", + // Application specific domain separator. Passed via `signature`. + bytes32(APP_DOMAIN_SEPARATOR), + keccak256( + abi.encode( + // Computed on-the-fly with `contentsType`, which is passed via `signature`. + typedDataSignTypehash, + // This is the `contents` struct hash, which is passed via `signature`. + bytes32(hashStruct(originalStruct)), + // `eip712Domain()` is from ERC-5267. + keccak256(bytes(eip712Domain().name)), + keccak256(bytes(eip712Domain().version)), + uint256(eip712Domain().chainId), + uint256(uint160(eip712Domain().verifyingContract)), + bytes32(eip712Domain().salt), + keccak256(abi.encodePacked(eip712Domain().extensions)) + ) + ) + ) + ); +``` + +where `typedDataSignTypehash` is: + +```solidity +typedDataSignTypehash = + keccak256( + abi.encodePacked( + "TypedDataSign(", + contentsTypeName, " contents", + "bytes1 fields,", + "string name,", + "string version,", + "uint256 chainId,", + "address verifyingContract,", + "bytes32 salt,", + "uint256[] extensions", + ")", + contentsType + ) + ); +``` + +If `contentsType` is `"Mail(address from,address to,string message)"`, then `contentsTypeName` will be `"Mail"`. + +The `contentsTypeName` is the substring of `contentsType` up to (excluding) the first instance of `"("`: + +In Solidity, this can be written as: + +```solidity +// `slice(string memory subject, uint256 start, uint256 end)` +// returns a copy of `subject` sliced from `start` to `end` (exclusive). +// `start` and `end` are byte offsets. +// +// `indexOf(string memory subject, string memory search)` +// Returns the byte index of the first location of `search` in `subject`, +// searching from left to right. Returns `2**256 - 1` if `search` is not found. +contentsTypeName = + LibString.slice( + contentsType, + 0, // Start byte index. + LibString.indexOf(contentsType, "(") // End byte index (exclusive). + ); +``` + +A copy of the `LibString` Solidity library is provided for reference in [`/assets/eip-7739/contracts/utils/LibString.sol`]. + +For safety, smart accounts MUST treat the signature as invalid if any of the following is true: + +- `contentsTypeName` is the empty string (i.e. `bytes(contentsTypeName).length == 0`). +- `contentsTypeName` starts with any of the following bytes `abcdefghijklmnopqrstuvwxyz(`. +- `contentsTypeName` contains any of the following bytes `, )\x00`. + +#### `TypedDataSign` signature + +The `signature` passed into `isValidSignature` will be changed to: + +``` +originalSignature ‖ APP_DOMAIN_SEPARATOR ‖ contents ‖ contentsType ‖ uint16(contentsType.length) +``` + +where `contents` is the bytes32 struct hash of the original struct. + +In Solidity, this can be written as: + +```solidity +signature = + abi.encodePacked( + bytes(originalSignature), + bytes32(APP_DOMAIN_SEPARATOR), + bytes32(contents), + bytes(contentsType), + uint16(contentsType.length) + ); +``` + +The appended `APP_DOMAIN_SEPARATOR` and `contents` struct hash will be used to verify if the `hash` passed into `isValidSignature` is indeed correct via: + +```solidity +hash == keccak256( + abi.encodePacked( + hex"1901", + bytes32(APP_DOMAIN_SEPARATOR), + bytes32(contents) + ) +) +``` + +If the `hash` does not match the reconstructed hash, then the `hash` and `signature` are invalid under the `TypedDataSign` workflow. + +### `PersonalSign` workflow + +This `PersonalSign` workflow handles the case where the `hash` is originally computed with [EIP-191](./eip-191.md). + +#### `PersonalSign` final hash + +The final hash for the `PersonalSign` workflow is defined as: + +``` +keccak256(\x19\x01 ‖ ACCOUNT_DOMAIN_SEPARATOR ‖ + hashStruct(PersonalSign({ + prefixed: keccak256(bytes(\x19Ethereum Signed Message:\n ‖ + base10(bytes(someString).length) ‖ someString)) + })) +) +``` + +where `‖` denotes the concatenation operator for bytes. + +In Solidity, this can be written as: + +```solidity +finalPersonalSignHash = + keccak256( + abi.encodePacked( + hex"1901", + // Smart account domain separator. + // Can be computed via `eip712Domain()` from ERC-5267. + bytes32(ACCOUNT_DOMAIN_SEPARATOR), + keccak256( + abi.encode( + // `PERSONAL_SIGN_TYPEHASH`. + keccak256("PersonalSign(bytes prefixed)"), + // `hash` is from `isValidSignature(hash, signature)` + hash + ) + ) + ) + ); +``` + +Here, `hash` is computed in the application contract and passed into `isValidSignature`. + +The smart account does not need to know how `hash` is computed. For completeness, this is how it can be computed: + +```solidity +hash = + abi.encodePacked( + "\x19Ethereum Signed Message:\n", + // `toString` returns the base10 representation of a uint256. + LibString.toString(someString.length), + // This is the original message to be signed. + someString + ); +``` + +#### `PersonalSign` signature + +The `PersonalSign` workflow does not require additional data to be appended to the `signature` passed into `isValidSignature`. + +### `supportsNestedTypedDataSign` function for detection + +To facilitate automatic detection, smart accounts SHOULD implement the following function: + +```solidity +/// @dev For automatic detection that the smart account supports the nested EIP-712 workflow. +/// By default, it returns `bytes32(bytes4(keccak256("supportsNestedTypedDataSign()")))`, +/// denoting support for the default behavior, as implemented in +/// `_erc1271IsValidSignatureViaNestedEIP712`, which is called in `isValidSignature`. +/// Future extensions should return a different non-zero `result` to denote different behavior. +/// This method intentionally returns bytes32 to allow freedom for future extensions. +function supportsNestedTypedDataSign() public view virtual returns (bytes32 result) { + result = bytes4(0xd620c85a); +} +``` + +### Signature verification workflow deduction + +As the `isValidSignature` signature function signature is unchanged, the implementation MUST be able to deduce the type of workflow required to verify the signature. + +If the signature contains the correct data to reconstruct the `hash`, the `isValidSignature` function MUST perform the `TypedDataSign` workflow. +Otherwise, the `isValidSignature` function MUST perform the `PersonalSign` workflow. + +In Solidity, the check can be written as: + +```solidity +// If this is true, it means that the `signature` contains +// the correct `APP_DOMAIN_SEPARATOR` and `contents`, +// and the `TypedDataSign` workflow MUST be performed. +// Otherwise, the `PersonalSign` workflow MUST be performed. +hash == keccak256( + abi.encodePacked( + hex"1901", + bytes32(APP_DOMAIN_SEPARATOR), + bytes32(contents) + ) +) +``` + +### Conditional skipping of defensive rehashing + +Smart accounts MAY skip the defensive rehashing workflows if any of the following is true: + +- `isValidSignature` is called off-chain. +- The `hash` passed into `isValidSignature` has already included the address of the smart account. + +As many developers may not update their applications to support the nested EIP-712 workflow, smart account implementations SHOULD try to accommodate by skipping the defensive rehashing where it is safe to do so. + +## Rationale + +### `TypedDataSign` structure + +The `typedDataSignTypehash` must be constructed on-the-fly on-chain. This is to enforce that the signed contents will be visible in the signature request, by requiring that `contents` be a user defined type. + +The structure is intentionally made flat with the fields of `eip712Domain` to make implementation feasible. Otherwise, smart accounts must implement on-chain lexographical sorting of strings for the struct type names when constructing `typedDataSignTypehash`. + +### `supportsNestedTypedDataSign` for detection + +Without this function, this standard will not change the interface of the smart account, as it defines the behavior of `isValidSignature` without adding any new functions. As such, [ERC-165](./eip-165.md) cannot be used. + +For future extendability, `supportsNestedTypedDataSign` is defined to return a bytes32 as the first word of its returned data. For bytecode compactness and to leave space for bit packing, only the leftmost 4 bytes are set to the function selector of `supportsNestedTypedDataSign`. + +The `supportsNestedTypedDataSign` function may be extended to return multiple values (e.g. `bytes32 result, bytes memory data`), as long as the first word of the returned data is a bytes32 identifier. This will not change the function selector. + +## Backwards Compatibility + +No backwards compatibility issues. + +## Reference Implementation + +A production ready and optimized reference implementation is provided at [`/assets/eip-7739/contracts/accounts/ERC1271.sol`]. + +It includes relevant complementary features required for safety, flexibility, developer experience, and user experience. + +The reference implementation is intentionally not minimalistic. This is to avoid repeating the mistake of [ERC-1271](./eip-1271.md), where a minimalist reference implementation is wrongly assumed to be safe for production use. + +## Security Considerations + +### Rejecting invalid `contentsTypeName` + +Current major implementations of `eth_signTypedData` do not sanitize the names of custom types. + +A phishing website can craft a `contentsTypeName` with control characters to break out of the `PersonalSign` type encoding, resulting in the wallet client asking the user to sign an opaque hash. + +Requiring on-chain sanitization of `contentsTypeName` will block this phishing attack vector. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). diff --git a/assets/erc-7739/contracts/accounts/ERC1271.sol b/assets/erc-7739/contracts/accounts/ERC1271.sol new file mode 100644 index 0000000000..c28e00ca10 --- /dev/null +++ b/assets/erc-7739/contracts/accounts/ERC1271.sol @@ -0,0 +1,320 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.4; + +import {EIP712} from "../utils/EIP712.sol"; +import {SignatureCheckerLib} from "../utils/SignatureCheckerLib.sol"; + +/// @notice ERC1271 mixin with nested EIP-712 approach. +/// @author Solady (https://github.com/vectorized/solady/blob/main/src/accounts/ERC1271.sol) +abstract contract ERC1271 is EIP712 { + /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ + /* CONSTANTS */ + /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ + + /// @dev `keccak256("PersonalSign(bytes prefixed)")`. + bytes32 internal constant _PERSONAL_SIGN_TYPEHASH = + 0x983e65e5148e570cd828ead231ee759a8d7958721a768f93bc4483ba005c32de; + + /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ + /* ERC1271 OPERATIONS */ + /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ + + /// @dev Validates the signature with ERC1271 return, + /// so that this account can also be used as a signer. + function isValidSignature(bytes32 hash, bytes calldata signature) + public + view + virtual + returns (bytes4 result) + { + bool success = _erc1271IsValidSignature(hash, _erc1271UnwrapSignature(signature)); + /// @solidity memory-safe-assembly + assembly { + // `success ? bytes4(keccak256("isValidSignature(bytes32,bytes)")) : 0xffffffff`. + // We use `0xffffffff` for invalid, in convention with the reference implementation. + result := shl(224, or(0x1626ba7e, sub(0, iszero(success)))) + } + } + + /// @dev For automatic detection that the smart account supports the nested EIP-712 workflow. + /// By default, it returns `bytes32(bytes4(keccak256("supportsNestedTypedDataSign()")))`, + /// denoting support for the default behavior, as implemented in + /// `_erc1271IsValidSignatureViaNestedEIP712`, which is called in `isValidSignature`. + /// Future extensions should return a different non-zero `result` to denote different behavior. + /// This method intentionally returns bytes32 to allow freedom for future extensions. + function supportsNestedTypedDataSign() public view virtual returns (bytes32 result) { + result = bytes4(0xd620c85a); + } + + /// @dev Returns the ERC1271 signer. + /// Override to return the signer `isValidSignature` checks against. + function _erc1271Signer() internal view virtual returns (address); + + /// @dev Returns whether the `msg.sender` is considered safe, such + /// that we don't need to use the nested EIP-712 workflow. + /// Override to return true for more callers. + /// See: https://mirror.xyz/curiousapple.eth/pFqAdW2LiJ-6S4sg_u1z08k4vK6BCJ33LcyXpnNb8yU + function _erc1271CallerIsSafe() internal view virtual returns (bool) { + // The canonical `MulticallerWithSigner` at 0x000000000000D9ECebf3C23529de49815Dac1c4c + // is known to include the account in the hash to be signed. + return msg.sender == 0x000000000000D9ECebf3C23529de49815Dac1c4c; + } + + /// @dev Returns whether the `hash` and `signature` are valid. + /// Override if you need non-ECDSA logic. + function _erc1271IsValidSignatureNowCalldata(bytes32 hash, bytes calldata signature) + internal + view + virtual + returns (bool) + { + return SignatureCheckerLib.isValidSignatureNowCalldata(_erc1271Signer(), hash, signature); + } + + /// @dev Unwraps and returns the signature. + function _erc1271UnwrapSignature(bytes calldata signature) + internal + view + virtual + returns (bytes calldata result) + { + result = signature; + /// @solidity memory-safe-assembly + assembly { + // Unwraps the ERC6492 wrapper if it exists. + // See: https://eips.ethereum.org/EIPS/eip-6492 + if eq( + calldataload(add(result.offset, sub(result.length, 0x20))), + mul(0x6492, div(not(mload(0x60)), 0xffff)) // `0x6492...6492`. + ) { + let o := add(result.offset, calldataload(add(result.offset, 0x40))) + result.length := calldataload(o) + result.offset := add(o, 0x20) + } + } + } + + /// @dev Returns whether the `signature` is valid for the `hash. + function _erc1271IsValidSignature(bytes32 hash, bytes calldata signature) + internal + view + virtual + returns (bool) + { + return _erc1271IsValidSignatureViaSafeCaller(hash, signature) + || _erc1271IsValidSignatureViaNestedEIP712(hash, signature) + || _erc1271IsValidSignatureViaRPC(hash, signature); + } + + /// @dev Performs the signature validation without nested EIP-712 if the caller is + /// a safe caller. A safe caller must include the address of this account in the hash. + function _erc1271IsValidSignatureViaSafeCaller(bytes32 hash, bytes calldata signature) + internal + view + virtual + returns (bool result) + { + if (_erc1271CallerIsSafe()) result = _erc1271IsValidSignatureNowCalldata(hash, signature); + } + + /// @dev ERC1271 signature validation (Nested EIP-712 workflow). + /// + /// This uses ECDSA recovery by default (see: `_erc1271IsValidSignatureNowCalldata`). + /// It also uses a nested EIP-712 approach to prevent signature replays when a single EOA + /// owns multiple smart contract accounts, + /// while still enabling wallet UIs (e.g. Metamask) to show the EIP-712 values. + /// + /// Crafted for phishing resistance, efficiency, flexibility. + /// __________________________________________________________________________________________ + /// + /// Glossary: + /// + /// - `APP_DOMAIN_SEPARATOR`: The domain separator of the `hash` passed in by the application. + /// Provided by the front end. Intended to be the domain separator of the contract + /// that will call `isValidSignature` on this account. + /// + /// - `ACCOUNT_DOMAIN_SEPARATOR`: The domain separator of this account. + /// See: `EIP712._domainSeparator()`. + /// __________________________________________________________________________________________ + /// + /// For the `TypedDataSign` workflow, the final hash will be: + /// ``` + /// keccak256(\x19\x01 ‖ APP_DOMAIN_SEPARATOR ‖ + /// hashStruct(TypedDataSign({ + /// contents: hashStruct(originalStruct), + /// name: keccak256(bytes(eip712Domain().name)), + /// version: keccak256(bytes(eip712Domain().version)), + /// chainId: eip712Domain().chainId, + /// verifyingContract: eip712Domain().verifyingContract, + /// salt: eip712Domain().salt, + /// extensions: keccak256(abi.encodePacked(eip712Domain().extensions)) + /// })) + /// ) + /// ``` + /// where `‖` denotes the concatenation operator for bytes. + /// The order of the fields is important: `contents` comes before `name`. + /// + /// The signature will be `r ‖ s ‖ v ‖ + /// APP_DOMAIN_SEPARATOR ‖ contents ‖ contentsType ‖ uint16(contentsType.length)`, + /// where `contents` is the bytes32 struct hash of the original struct. + /// + /// The `APP_DOMAIN_SEPARATOR` and `contents` will be used to verify if `hash` is indeed correct. + /// __________________________________________________________________________________________ + /// + /// For the `PersonalSign` workflow, the final hash will be: + /// ``` + /// keccak256(\x19\x01 ‖ ACCOUNT_DOMAIN_SEPARATOR ‖ + /// hashStruct(PersonalSign({ + /// prefixed: keccak256(bytes(\x19Ethereum Signed Message:\n ‖ + /// base10(bytes(someString).length) ‖ someString)) + /// })) + /// ) + /// ``` + /// where `‖` denotes the concatenation operator for bytes. + /// + /// The `PersonalSign` type hash will be `keccak256("PersonalSign(bytes prefixed)")`. + /// The signature will be `r ‖ s ‖ v`. + /// __________________________________________________________________________________________ + /// + /// For demo and typescript code, see: + /// - https://github.com/junomonster/nested-eip-712 + /// - https://github.com/frangio/eip712-wrapper-for-eip1271 + /// + /// Their nomenclature may differ from ours, although the high-level idea is similar. + /// + /// Of course, if you have control over the codebase of the wallet client(s) too, + /// you can choose a more minimalistic signature scheme like + /// `keccak256(abi.encode(address(this), hash))` instead of all these acrobatics. + /// All these are just for widespread out-of-the-box compatibility with other wallet clients. + /// We want to create bazaars, not walled castles. + /// And we'll use push the Turing Completeness of the EVM to the limits to do so. + function _erc1271IsValidSignatureViaNestedEIP712(bytes32 hash, bytes calldata signature) + internal + view + virtual + returns (bool result) + { + bytes32 t = _typedDataSignFields(); + /// @solidity memory-safe-assembly + assembly { + let m := mload(0x40) // Cache the free memory pointer. + // `c` is `contentsType.length`, which is stored in the last 2 bytes of the signature. + let c := shr(240, calldataload(add(signature.offset, sub(signature.length, 2)))) + for {} 1 {} { + let l := add(0x42, c) // Total length of appended data (32 + 32 + c + 2). + let o := add(signature.offset, sub(signature.length, l)) // Offset of appended data. + mstore(0x00, 0x1901) // Store the "\x19\x01" prefix. + calldatacopy(0x20, o, 0x40) // Copy the `APP_DOMAIN_SEPARATOR` and `contents` struct hash. + // Use the `PersonalSign` workflow if the reconstructed hash doesn't match, + // or if the appended data is invalid, i.e. + // `appendedData.length > signature.length || contentsType.length == 0`. + if or(xor(keccak256(0x1e, 0x42), hash), or(lt(signature.length, l), iszero(c))) { + t := 0 // Set `t` to 0, denoting that we need to `hash = _hashTypedData(hash)`. + mstore(t, _PERSONAL_SIGN_TYPEHASH) + mstore(0x20, hash) // Store the `prefixed`. + hash := keccak256(t, 0x40) // Compute the `PersonalSign` struct hash. + break + } + // Else, use the `TypedDataSign` workflow. + // `TypedDataSign({ContentsName} contents,bytes1 fields,...){ContentsType}`. + mstore(m, "TypedDataSign(") // Store the start of `TypedDataSign`'s type encoding. + let p := add(m, 0x0e) // Advance 14 bytes to skip "TypedDataSign(". + calldatacopy(p, add(o, 0x40), c) // Copy `contentsType` to extract `contentsName`. + // `d & 1 == 1` means that `contentsName` is invalid. + let d := shr(byte(0, mload(p)), 0x7fffffe000000000000010000000000) // Starts with `[a-z(]`. + // Store the end sentinel '(', and advance `p` until we encounter a '(' byte. + for { mstore(add(p, c), 40) } iszero(eq(byte(0, mload(p)), 40)) { p := add(p, 1) } { + d := or(shr(byte(0, mload(p)), 0x120100000001), d) // Has a byte in ", )\x00". + } + mstore(p, " contents,bytes1 fields,string n") // Store the rest of the encoding. + mstore(add(p, 0x20), "ame,string version,uint256 chain") + mstore(add(p, 0x40), "Id,address verifyingContract,byt") + mstore(add(p, 0x60), "es32 salt,uint256[] extensions)") + p := add(p, 0x7f) + calldatacopy(p, add(o, 0x40), c) // Copy `contentsType`. + // Fill in the missing fields of the `TypedDataSign`. + calldatacopy(t, o, 0x40) // Copy the `contents` struct hash to `add(t, 0x20)`. + mstore(t, keccak256(m, sub(add(p, c), m))) // Store `typedDataSignTypehash`. + // The "\x19\x01" prefix is already at 0x00. + // `APP_DOMAIN_SEPARATOR` is already at 0x20. + mstore(0x40, keccak256(t, 0x120)) // `hashStruct(typedDataSign)`. + // Compute the final hash, corrupted if `contentsName` is invalid. + hash := keccak256(0x1e, add(0x42, and(1, d))) + signature.length := sub(signature.length, l) // Truncate the signature. + break + } + mstore(0x40, m) // Restore the free memory pointer. + } + if (t == bytes32(0)) hash = _hashTypedData(hash); // `PersonalSign` workflow. + result = _erc1271IsValidSignatureNowCalldata(hash, signature); + } + + /// @dev For use in `_erc1271IsValidSignatureViaNestedEIP712`, + function _typedDataSignFields() private view returns (bytes32 m) { + ( + bytes1 fields, + string memory name, + string memory version, + uint256 chainId, + address verifyingContract, + bytes32 salt, + uint256[] memory extensions + ) = eip712Domain(); + /// @solidity memory-safe-assembly + assembly { + m := mload(0x40) // Grab the free memory pointer. + mstore(0x40, add(m, 0x120)) // Allocate the memory. + // Skip 2 words for the `typedDataSignTypehash` and `contents` struct hash. + mstore(add(m, 0x40), shl(248, byte(0, fields))) + mstore(add(m, 0x60), keccak256(add(name, 0x20), mload(name))) + mstore(add(m, 0x80), keccak256(add(version, 0x20), mload(version))) + mstore(add(m, 0xa0), chainId) + mstore(add(m, 0xc0), shr(96, shl(96, verifyingContract))) + mstore(add(m, 0xe0), salt) + mstore(add(m, 0x100), keccak256(add(extensions, 0x20), shl(5, mload(extensions)))) + } + } + + /// @dev Performs the signature validation without nested EIP-712 to allow for easy sign ins. + /// This function must always return false or revert if called on-chain. + function _erc1271IsValidSignatureViaRPC(bytes32 hash, bytes calldata signature) + internal + view + virtual + returns (bool result) + { + // Non-zero gasprice is a heuristic to check if a call is on-chain, + // but we can't fully depend on it because it can be manipulated. + // See: https://x.com/NoahCitron/status/1580359718341484544 + if (tx.gasprice == uint256(0)) { + /// @solidity memory-safe-assembly + assembly { + mstore(gasprice(), gasprice()) // `mstore(0x00, 0x00)`. + // Basefee contract. + // See: https://gist.github.com/Vectorized/3c9b63524d57492b265454f62d895f71 + // We'll use an external contract to retrieve the basefee, + // because solc 0.8.4 and some chains do not support the basefee opcode. + // In absence of this contract, the basefee will be treated as zero. + let b := 0x000000000000378eDCD5B5B0A24f5342d8C10485 + pop(staticcall(0xffff, b, codesize(), gasprice(), gasprice(), 0x20)) + // If `gasprice < basefee`, the call cannot be on-chain, and we can skip the gas burn. + if iszero(mload(gasprice())) { + let m := mload(0x40) // Cache the free memory pointer. + mstore(gasprice(), 0x1626ba7e) // `isValidSignature(bytes32,bytes)`. + mstore(0x20, b) // Recycle `b` to denote if we need to burn gas. + mstore(0x40, 0x40) + let gasToBurn := or(add(0xffff, gaslimit()), gaslimit()) + // Burns gas computationally efficiently. Also, requires that `gas > gasToBurn`. + if or(eq(hash, b), lt(gas(), gasToBurn)) { invalid() } + // Make a call to this with `b`, efficiently burning the gas provided. + // No valid transaction can consume more than the gaslimit. + // See: https://ethereum.github.io/yellowpaper/paper.pdf + // Most RPCs perform calls with a gas budget greater than the gaslimit. + pop(staticcall(gasToBurn, address(), 0x1c, 0x64, gasprice(), gasprice())) + mstore(0x40, m) // Restore the free memory pointer. + } + } + result = _erc1271IsValidSignatureNowCalldata(hash, signature); + } + } +} diff --git a/assets/erc-7739/contracts/utils/EIP712.sol b/assets/erc-7739/contracts/utils/EIP712.sol new file mode 100644 index 0000000000..f77ee14983 --- /dev/null +++ b/assets/erc-7739/contracts/utils/EIP712.sol @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.4; + +/// @notice Contract for EIP-712 typed structured data hashing and signing. +/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/EIP712.sol) +/// @author Modified from Solbase (https://github.com/Sol-DAO/solbase/blob/main/src/utils/EIP712.sol) +/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/EIP712.sol) +/// +/// @dev Note, this implementation: +/// - Uses `address(this)` for the `verifyingContract` field. +/// - Does NOT use the optional EIP-712 salt. +/// - Does NOT use any EIP-712 extensions. +/// This is for simplicity and to save gas. +/// If you need to customize, please fork / modify accordingly. +abstract contract EIP712 { + /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ + /* CONSTANTS AND IMMUTABLES */ + /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ + + /// @dev `keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")`. + bytes32 internal constant _DOMAIN_TYPEHASH = + 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f; + + uint256 private immutable _cachedThis; + uint256 private immutable _cachedChainId; + bytes32 private immutable _cachedNameHash; + bytes32 private immutable _cachedVersionHash; + bytes32 private immutable _cachedDomainSeparator; + + /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ + /* CONSTRUCTOR */ + /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ + + /// @dev Cache the hashes for cheaper runtime gas costs. + /// In the case of upgradeable contracts (i.e. proxies), + /// or if the chain id changes due to a hard fork, + /// the domain separator will be seamlessly calculated on-the-fly. + constructor() { + _cachedThis = uint256(uint160(address(this))); + _cachedChainId = block.chainid; + + string memory name; + string memory version; + if (!_domainNameAndVersionMayChange()) (name, version) = _domainNameAndVersion(); + bytes32 nameHash = _domainNameAndVersionMayChange() ? bytes32(0) : keccak256(bytes(name)); + bytes32 versionHash = + _domainNameAndVersionMayChange() ? bytes32(0) : keccak256(bytes(version)); + _cachedNameHash = nameHash; + _cachedVersionHash = versionHash; + + bytes32 separator; + if (!_domainNameAndVersionMayChange()) { + /// @solidity memory-safe-assembly + assembly { + let m := mload(0x40) // Load the free memory pointer. + mstore(m, _DOMAIN_TYPEHASH) + mstore(add(m, 0x20), nameHash) + mstore(add(m, 0x40), versionHash) + mstore(add(m, 0x60), chainid()) + mstore(add(m, 0x80), address()) + separator := keccak256(m, 0xa0) + } + } + _cachedDomainSeparator = separator; + } + + /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ + /* FUNCTIONS TO OVERRIDE */ + /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ + + /// @dev Please override this function to return the domain name and version. + /// ``` + /// function _domainNameAndVersion() + /// internal + /// pure + /// virtual + /// returns (string memory name, string memory version) + /// { + /// name = "Solady"; + /// version = "1"; + /// } + /// ``` + /// + /// Note: If the returned result may change after the contract has been deployed, + /// you must override `_domainNameAndVersionMayChange()` to return true. + function _domainNameAndVersion() + internal + view + virtual + returns (string memory name, string memory version); + + /// @dev Returns if `_domainNameAndVersion()` may change + /// after the contract has been deployed (i.e. after the constructor). + /// Default: false. + function _domainNameAndVersionMayChange() internal pure virtual returns (bool result) {} + + /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ + /* HASHING OPERATIONS */ + /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ + + /// @dev Returns the EIP-712 domain separator. + function _domainSeparator() internal view virtual returns (bytes32 separator) { + if (_domainNameAndVersionMayChange()) { + separator = _buildDomainSeparator(); + } else { + separator = _cachedDomainSeparator; + if (_cachedDomainSeparatorInvalidated()) separator = _buildDomainSeparator(); + } + } + + /// @dev Returns the hash of the fully encoded EIP-712 message for this domain, + /// given `structHash`, as defined in + /// https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct. + /// + /// The hash can be used together with {ECDSA-recover} to obtain the signer of a message: + /// ``` + /// bytes32 digest = _hashTypedData(keccak256(abi.encode( + /// keccak256("Mail(address to,string contents)"), + /// mailTo, + /// keccak256(bytes(mailContents)) + /// ))); + /// address signer = ECDSA.recover(digest, signature); + /// ``` + function _hashTypedData(bytes32 structHash) internal view virtual returns (bytes32 digest) { + // We will use `digest` to store the domain separator to save a bit of gas. + if (_domainNameAndVersionMayChange()) { + digest = _buildDomainSeparator(); + } else { + digest = _cachedDomainSeparator; + if (_cachedDomainSeparatorInvalidated()) digest = _buildDomainSeparator(); + } + /// @solidity memory-safe-assembly + assembly { + // Compute the digest. + mstore(0x00, 0x1901000000000000) // Store "\x19\x01". + mstore(0x1a, digest) // Store the domain separator. + mstore(0x3a, structHash) // Store the struct hash. + digest := keccak256(0x18, 0x42) + // Restore the part of the free memory slot that was overwritten. + mstore(0x3a, 0) + } + } + + /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ + /* EIP-5267 OPERATIONS */ + /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ + + /// @dev See: https://eips.ethereum.org/EIPS/eip-5267 + function eip712Domain() + public + view + virtual + returns ( + bytes1 fields, + string memory name, + string memory version, + uint256 chainId, + address verifyingContract, + bytes32 salt, + uint256[] memory extensions + ) + { + fields = hex"0f"; // `0b01111`. + (name, version) = _domainNameAndVersion(); + chainId = block.chainid; + verifyingContract = address(this); + salt = salt; // `bytes32(0)`. + extensions = extensions; // `new uint256[](0)`. + } + + /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ + /* PRIVATE HELPERS */ + /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ + + /// @dev Returns the EIP-712 domain separator. + function _buildDomainSeparator() private view returns (bytes32 separator) { + // We will use `separator` to store the name hash to save a bit of gas. + bytes32 versionHash; + if (_domainNameAndVersionMayChange()) { + (string memory name, string memory version) = _domainNameAndVersion(); + separator = keccak256(bytes(name)); + versionHash = keccak256(bytes(version)); + } else { + separator = _cachedNameHash; + versionHash = _cachedVersionHash; + } + /// @solidity memory-safe-assembly + assembly { + let m := mload(0x40) // Load the free memory pointer. + mstore(m, _DOMAIN_TYPEHASH) + mstore(add(m, 0x20), separator) // Name hash. + mstore(add(m, 0x40), versionHash) + mstore(add(m, 0x60), chainid()) + mstore(add(m, 0x80), address()) + separator := keccak256(m, 0xa0) + } + } + + /// @dev Returns if the cached domain separator has been invalidated. + function _cachedDomainSeparatorInvalidated() private view returns (bool result) { + uint256 cachedChainId = _cachedChainId; + uint256 cachedThis = _cachedThis; + /// @solidity memory-safe-assembly + assembly { + result := iszero(and(eq(chainid(), cachedChainId), eq(address(), cachedThis))) + } + } +} diff --git a/assets/erc-7739/contracts/utils/LibString.sol b/assets/erc-7739/contracts/utils/LibString.sol new file mode 100644 index 0000000000..cb67e372e3 --- /dev/null +++ b/assets/erc-7739/contracts/utils/LibString.sol @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.4; + +/// @notice Library for converting numbers into strings and other string operations. +/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibString.sol) +/// +/// @dev Note: +/// For performance and bytecode compactness, most of the string operations are restricted to +/// byte strings (7-bit ASCII), except where otherwise specified. +/// Usage of byte string operations on charsets with runes spanning two or more bytes +/// can lead to undefined behavior. +library LibString { + /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ + /* CONSTANTS */ + /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ + + /// @dev The constant returned when the `search` is not found in the string. + uint256 internal constant NOT_FOUND = type(uint256).max; + + /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ + /* DECIMAL OPERATIONS */ + /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ + + /// @dev Returns the base 10 decimal representation of `value`. + function toString(uint256 value) internal pure returns (string memory str) { + /// @solidity memory-safe-assembly + assembly { + // The maximum value of a uint256 contains 78 digits (1 byte per digit), but + // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. + // We will need 1 word for the trailing zeros padding, 1 word for the length, + // and 3 words for a maximum of 78 digits. + str := add(mload(0x40), 0x80) + mstore(0x40, add(str, 0x20)) // Allocate the memory. + mstore(str, 0) // Zeroize the slot after the string. + + let end := str // Cache the end of the memory to calculate the length later. + let w := not(0) + // We write the string from rightmost digit to leftmost digit. + // The following is essentially a do-while loop that also handles the zero case. + for { let temp := value } 1 {} { + str := add(str, w) // `sub(str, 1)`. + // Store the character to the pointer. + // The ASCII index of the '0' character is 48. + mstore8(str, add(48, mod(temp, 10))) + temp := div(temp, 10) // Keep dividing `temp` until zero. + if iszero(temp) { break } + } + let length := sub(end, str) + str := sub(str, 0x20) // Move the pointer 32 bytes back to make room for the length. + mstore(str, length) // Store the length. + } + } + + /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ + /* BYTE STRING OPERATIONS */ + /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ + + // For performance and bytecode compactness, byte string operations are restricted + // to 7-bit ASCII strings. All offsets are byte offsets, not UTF character offsets. + // Usage of byte string operations on charsets with runes spanning two or more bytes + // can lead to undefined behavior. + + /// @dev Returns the byte index of the first location of `search` in `subject`, + /// searching from left to right, starting from `from`. + /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found. + function indexOf(string memory subject, string memory search, uint256 from) + internal + pure + returns (uint256 result) + { + /// @solidity memory-safe-assembly + assembly { + for { let subjectLength := mload(subject) } 1 {} { + if iszero(mload(search)) { + if iszero(gt(from, subjectLength)) { + result := from + break + } + result := subjectLength + break + } + let searchLength := mload(search) + let subjectStart := add(subject, 0x20) + + result := not(0) // Initialize to `NOT_FOUND`. + subject := add(subjectStart, from) + let end := add(sub(add(subjectStart, subjectLength), searchLength), 1) + + let m := shl(3, sub(0x20, and(searchLength, 0x1f))) + let s := mload(add(search, 0x20)) + + if iszero(and(lt(subject, end), lt(from, subjectLength))) { break } + + if iszero(lt(searchLength, 0x20)) { + for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} { + if iszero(shr(m, xor(mload(subject), s))) { + if eq(keccak256(subject, searchLength), h) { + result := sub(subject, subjectStart) + break + } + } + subject := add(subject, 1) + if iszero(lt(subject, end)) { break } + } + break + } + for {} 1 {} { + if iszero(shr(m, xor(mload(subject), s))) { + result := sub(subject, subjectStart) + break + } + subject := add(subject, 1) + if iszero(lt(subject, end)) { break } + } + break + } + } + } + + /// @dev Returns the byte index of the first location of `search` in `subject`, + /// searching from left to right. + /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found. + function indexOf(string memory subject, string memory search) + internal + pure + returns (uint256 result) + { + result = indexOf(subject, search, 0); + } + + /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive). + /// `start` and `end` are byte offsets. + function slice(string memory subject, uint256 start, uint256 end) + internal + pure + returns (string memory result) + { + /// @solidity memory-safe-assembly + assembly { + let subjectLength := mload(subject) + if iszero(gt(subjectLength, end)) { end := subjectLength } + if iszero(gt(subjectLength, start)) { start := subjectLength } + if lt(start, end) { + result := mload(0x40) + let resultLength := sub(end, start) + mstore(result, resultLength) + subject := add(subject, start) + let w := not(0x1f) + // Copy the `subject` one word at a time, backwards. + for { let o := and(add(resultLength, 0x1f), w) } 1 {} { + mstore(add(result, o), mload(add(subject, o))) + o := add(o, w) // `sub(o, 0x20)`. + if iszero(o) { break } + } + // Zeroize the slot after the string. + mstore(add(add(result, 0x20), resultLength), 0) + mstore(0x40, add(result, add(resultLength, 0x40))) // Allocate the memory. + } + } + } + + /// @dev Returns a copy of `subject` sliced from `start` to the end of the string. + /// `start` is a byte offset. + function slice(string memory subject, uint256 start) + internal + pure + returns (string memory result) + { + result = slice(subject, start, uint256(int256(-1))); + } +} diff --git a/assets/erc-7739/contracts/utils/SignatureCheckerLib.sol b/assets/erc-7739/contracts/utils/SignatureCheckerLib.sol new file mode 100644 index 0000000000..cd790c74f8 --- /dev/null +++ b/assets/erc-7739/contracts/utils/SignatureCheckerLib.sol @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.4; + +/// @notice Signature verification helper that supports both ECDSA signatures from EOAs +/// and ERC1271 signatures from smart contract wallets like Argent and Gnosis safe. +/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SignatureCheckerLib.sol) +/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/SignatureChecker.sol) +/// +/// @dev Note: +/// - The signature checking functions use the ecrecover precompile (0x1). +/// - Unlike ECDSA signatures, contract signatures are revocable. +/// - All `bytes signature` variants accept both +/// regular 65-byte `(r, s, v)` and EIP-2098 `(r, vs)` short form signatures. +/// See: https://eips.ethereum.org/EIPS/eip-2098 +/// This is for calldata efficiency on smart accounts prevalent on L2s. +/// +/// WARNING! Do NOT use signatures as unique identifiers: +/// - Use a nonce in the digest to prevent replay attacks on the same contract. +/// - Use EIP-712 for the digest to prevent replay attacks across different chains and contracts. +/// EIP-712 also enables readable signing of typed data for better user safety. +/// This implementation does NOT check if a signature is non-malleable. +library SignatureCheckerLib { + /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ + /* SIGNATURE CHECKING OPERATIONS */ + /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ + + /// @dev Returns whether `signature` is valid for `signer` and `hash`. + /// If `signer` is a smart contract, the signature is validated with ERC1271. + /// Otherwise, the signature is validated with `ECDSA.recover`. + function isValidSignatureNowCalldata(address signer, bytes32 hash, bytes calldata signature) + internal + view + returns (bool isValid) + { + /// @solidity memory-safe-assembly + assembly { + // Clean the upper 96 bits of `signer` in case they are dirty. + for { signer := shr(96, shl(96, signer)) } signer {} { + let m := mload(0x40) + mstore(0x00, hash) + if eq(signature.length, 64) { + let vs := calldataload(add(signature.offset, 0x20)) + mstore(0x20, add(shr(255, vs), 27)) // `v`. + mstore(0x40, calldataload(signature.offset)) // `r`. + mstore(0x60, shr(1, shl(1, vs))) // `s`. + let t := + staticcall( + gas(), // Amount of gas left for the transaction. + 1, // Address of `ecrecover`. + 0x00, // Start of input. + 0x80, // Size of input. + 0x01, // Start of output. + 0x20 // Size of output. + ) + // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. + if iszero(or(iszero(returndatasize()), xor(signer, mload(t)))) { + isValid := 1 + mstore(0x60, 0) // Restore the zero slot. + mstore(0x40, m) // Restore the free memory pointer. + break + } + } + if eq(signature.length, 65) { + mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40)))) // `v`. + calldatacopy(0x40, signature.offset, 0x40) // `r`, `s`. + let t := + staticcall( + gas(), // Amount of gas left for the transaction. + 1, // Address of `ecrecover`. + 0x00, // Start of input. + 0x80, // Size of input. + 0x01, // Start of output. + 0x20 // Size of output. + ) + // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. + if iszero(or(iszero(returndatasize()), xor(signer, mload(t)))) { + isValid := 1 + mstore(0x60, 0) // Restore the zero slot. + mstore(0x40, m) // Restore the free memory pointer. + break + } + } + mstore(0x60, 0) // Restore the zero slot. + mstore(0x40, m) // Restore the free memory pointer. + + let f := shl(224, 0x1626ba7e) + mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. + mstore(add(m, 0x04), hash) + let d := add(m, 0x24) + mstore(d, 0x40) // The offset of the `signature` in the calldata. + mstore(add(m, 0x44), signature.length) + // Copy the `signature` over. + calldatacopy(add(m, 0x64), signature.offset, signature.length) + // forgefmt: disable-next-item + isValid := and( + // Whether the returndata is the magic value `0x1626ba7e` (left-aligned). + eq(mload(d), f), + // Whether the staticcall does not revert. + // This must be placed at the end of the `and` clause, + // as the arguments are evaluated from right to left. + staticcall( + gas(), // Remaining gas. + signer, // The `signer` address. + m, // Offset of calldata in memory. + add(signature.length, 0x64), // Length of calldata in memory. + d, // Offset of returndata. + 0x20 // Length of returndata to write. + ) + ) + break + } + } + } +} From 289221d9af1054f1ce4c7b098b678f3cd4e56e38 Mon Sep 17 00:00:00 2001 From: ivica7 Date: Mon, 14 Oct 2024 05:08:08 +0200 Subject: [PATCH 20/46] Add ERC: Opaque Token Merged by EIP-Bot. --- ERCS/erc-7722.md | 328 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 328 insertions(+) create mode 100644 ERCS/erc-7722.md diff --git a/ERCS/erc-7722.md b/ERCS/erc-7722.md new file mode 100644 index 0000000000..29756670dd --- /dev/null +++ b/ERCS/erc-7722.md @@ -0,0 +1,328 @@ +--- +eip: 7722 +title: Opaque Token +description: A token specification designed to enhance privacy by concealing balance information. +author: Ivica Aračić (@ivica7), SWIAT +discussions-to: https://ethereum-magicians.org/t/erc-7722-opaque-token/20249 +status: Draft +type: Standards Track +category: ERC +created: 2024-06-09 +--- + +## Abstract + +This ERC proposes a specification for an opaque token that enhances privacy by concealing balance information. Privacy is achieved by representing balances as off-chain data encapsulated in hashes, referred to as "baskets". These baskets can be reorganized, transferred, and managed through token functions on-chain. + +## Motivation + +Smart contract accounts serve as well-defined identities that can have reusable claims and attestations attached to them, making them highly useful for various applications. However, this strength also introduces a significant privacy challenge when these identities are used to hold tokens. Specifically, in the case of [ERC-20](./eip-20.html) compatible tokens, where balances are stored directly on-chain in plain text, the transparency of these balances can compromise the privacy of the account holder. This creates a dilemma: while the reuse of claims and attestations tied to a smart contract account can be advantageous, it also increases the risk of exposing sensitive financial information, particularly when these well-defined identities are associated with publicly visible token holdings. + +This proposal aims to conceal balances on-chain, allowing the use of smart contract accounts to hold tokens without compromising privacy or integrity. + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +The concept revolves around representing token balances on-chain as hashed values, called baskets, which obscure the actual balance information. These baskets combine a random salt, a unique token ID, and the token's value, making it impossible to derive the token's value directly from the blockchain. + +The token interface allows for creating, transferring, minting, and reorganizing (splitting and joining) these baskets. To prevent unauthorized changes and maintain integrity, oracle services verify that the total value of baskets remains consistent during reorganizations. Additionally, differential privacy techniques, such as overlaying noise and empty transfers, further protect privacy by making it difficult to trace token movements and determine actual transaction details. + +### Baskets + +Balances are represented on-chain as hashes of the form: + +``` +keccak256(abi.encode(salt, tokenId, value)) + +// where salt (bytes32) - random 32bytes to increase the entropy and +// make brute-forcing the hash impossible +// tokenId (bytes32) - a unique tokenId within token's smart contract instance +// value (uint256) - the value of the position +``` + +For the remainder of this document, we refer to these hashes as "baskets" because they conceal the balance information in an opaque manner, similar to how a covered basket hides its contents. + +### Token Interface + +An opaque token MUST implement the following interface. + +``` +interface OpaqueToken { + // + // TYPES + // + + struct SIGNATURE { + uint8 v; bytes32 r; bytes32 s; + } + + struct ORACLECONFIG { + uint8 minNumberOfOracles; // min. number of oracle signatures required for reorg + address[] oracles; // valid oracles + } + + // + // EVENTS + // + + event CreateToken(address initiatedBy, bytes32 tokenId, bytes32 totalSupplyBasket, bytes32 ref); + event Mint(address initiatedBy, bytes32[] baskets, bytes32 ref); + event ReorgHolderBaskets(address initiatedBy, bytes32[] basketsIn, bytes32[] basketsOut, bytes32 ref); + event ReorgSupplyBaskets(address initiatedBy, bytes32[] basketsIn, bytes32[] basketsOut, bytes32 ref); + event Transfer(address initiatedBy, address receiver, bytes32[] baskets, bytes32 ref); + event Burn(address initiatedBy, bytes32[] baskets, bytes32 ref); + + // + // FUNCTIONS + // + + /** + * @dev returns the configuration for this token + */ + function oracleConfig() external view returns (ORACLECONFIG memory); + + /** + * @dev returns the address of the basket owner + */ + function owner(bytes32 basket) external view returns (address); + + /** + * @dev returns the total supply for a `tokenId`` + * All token investors are allowed to fetch this value from the token operator's off-chain storage. + */ + function totalSupply(bytes32 tokenId) external view returns (bytes32); + + /** + * @dev returns the operator of this token, who is also responsible for providing the main + * off-chain storage source. + */ + function operator() external view returns (address); + + /** + * @dev Allows the token operator to create a new token with the specified `tokenId` and an initial + * `totalSupplyBasket`. The `totalSupplyBasket` can be partitioned using {reorgSupplyBaskets} as needed + * when calling {mint}. The `ref` parameter can be used freely by the caller for any reference purpose. + */ + function createToken( + bytes32 tokenId, + bytes32 totalSupplyBasket, + bytes32 ref + ) external; + + /** + * @dev Allows the token operator to mint tokens by assigning `supplyBaskets` to a `receiver` which + * becomes the owner of these baskets. + */ + function mint( + bytes32[] calldata supplyBaskets, + address receiver, + bytes32 ref + ) external; + + /** + * @dev transfers `baskets` to a `receiver` who becomes the new owner of these baskets. + */ + function transfer( + bytes32[] calldata baskets, + address receiver, + bytes32 ref + ) external; + + /** + * @dev reorganizes a set of holder baskets (`basketsIn`) to a new set (`basketsOut`) having + * the same value, i.e., the sum of all values from input baskets equals the sum of values + * in output baskets. In order to ensure the integrity, external oracle service is required that + * will sign the reorg proposal requested by the basket owner, which is passed as `reorgOracleSignatures`. + * The minimum number of oracle signatures is defined in the oracle configuration. + */ + function reorgHolderBaskets( + SIGNATURE[] calldata reorgOracleSignatures, + bytes32[] calldata basketsIn, + bytes32[] calldata basketsOut, + bytes32 ref + ) external; + + /** + * @dev same as {reorgHolderBaskets}, but for the available supply baskets. + */ + function reorgSupplyBaskets( + SIGNATURE[] calldata reorgOracleSignatures, + bytes32[] calldata basketsIn, + bytes32[] calldata basketsOut, + bytes32 ref + ) external; + + /** + * @dev burns holder's `baskets` and returns them to available supply + */ + function burn( + bytes32[] calldata baskets, + bytes32 ref + ) external; +} +``` + +### Off-chain Data Endpoints + +* The operator of the token (e.g., issuer or registrar) MUST provide the off-chain storage that implements the `GET basket` and `PUT basket` REST endpoints as described in this section. +* The operator MUST ensure the availability of the basket data and will share it on need-to-know basis with all eligible holders, i.e., with all address that either were holding the basket in the past or are currently the holder of the basket. +* To ensure data is only shared with and can be written by eligible holders, the operator MUST implement authentication for both endpoints. The concrete authentication schema is not specified here and my depend on the environment of the token operator. +* The operator MUST allow an existing token holder to `PUT basket` +* The operator MUST allow the current or historical basket holder to `GET basket` +* Token holders SHOULD store a copy of the data about their own baskets in their own off-chain storage for the case that operator's service is unavailable. + +REST API Endpoints for creating and querying baskets: + +``` + Endpoint: PUT baskets + Description: will store baskets if the `basket` hash is matching `data`. + PostData: + [ + { + basket: keccak256(abi.encode(salt, tokenId, value)), + data: { + salt: , + tokenId: , + value: + } + }, + ... + ] + + Endpoint: GET baskets?basket-hash= + Description: will return the list of baskets depending on the query parameters. + Query Parameters: + - basket-hash (optional): returns one basket matching the requested hash + - if no query parameter is set, then the endpoint will return all baskets of the requestor + Response: + [ + { + basket: keccak256(abi.encode(salt, tokenId, value)), + data: { + salt: , + tokenId: , + value: + } + }, + ... + ] +``` + +### reorg Endpoint + +To ensure the integrity of a reorg and avoid accidental or fraudulent mints or burns, an oracle services is required. + +* Oracles MUST provide a `POST reorg` REST Endpoint as described in this section +* Oracles MUST sign any reorg proposal request where + * the sum of values in input baskets grouped by tokenId is equal the sum of values of the output baskets grouped by tokenId. + * `item.basket` hash matches `keccak256(abi.encode(data.salt, data.tokenId, data.value))` +* The reorg endpoint MUST be stateless +* Oracle MUST NOT persist data from the request for later analysis. +* The reorg endpoint SHOULD NOT require authentication and can be used by anyone without restrictions. + +``` +Endpoint: POST reorg +PostData: +{ + in: [ + { + basket: keccak256(abi.encode(salt, tokenId, value)), + data: { + salt: , + tokenId: , + value: + } + }, + ... + ], + out: [ + { + basket: keccak256(abi.encode(salt, tokenId, value)), + data: { + salt: , + tokenId: , + value: + } + }, + ... + ] +} + +Response: { + // hash is signed with oracles private key + // basketsIn and basketsIn are bytes32[] + signature: sign(keccak256(abi.encode(basketsIn, basketsOut))) +} +``` + +Example for valid reorg requests (salt and hashes are omitted for better readability): + +``` +in : (..., token1, 10), (..., token1, 30), (..., token2, 5), (..., token2, 95) +out: (..., token1, 40), (..., token2, 100) + +in : (..., token1, 40), (..., token2, 100) +out: (..., token1, 10), (..., token1, 30), (..., token2, 5), (..., token2, 95) +``` + +### Overlaying Noise (Differential Privacy) + +To further enhance privacy and obscure transaction details, an additional layer of noise need to be introduced through reorgs and empty transfers. For example, received baskets can be reorganized into new baskets to prevent information leakage to the previous owner. Additionally, null-value baskets can be sent to random receivers (empty transfers), making it difficult for observers to determine who is transferring to whom. + +Example with reorg and null-value basket transfers: +``` +A owns basket-a1{..., value:10} +B owns basket-b1{..., value:5}, basket-b2{..., value:15}, ... +A: transfer basket-a1 to B +B: reorg [basket-a1, basket-b1, basket-b2] + to [basket-b3{..., value:10}, basket-b4{..., value:10}, basket-b5:{..., value:10}, + basket-b6:{..., value:0}, basket-b7:{..., value:0}] + where sum of inputs is the sum of outputs +B: transfer basket-b5{value:10} to C +B: transfer basket-b6{value:0} to D +B: transfer basket-b7{value:0} to E +``` + +If B would directly send basket-a1 to C, A would know what C is receiving, however, now that B has reorg'ed the baskets, A can not know anymore what has been sent to C. + +Moreover, observers still see who is communicating with whom, but since there is noise introduced, they can not tell which of these transfers are actually transferring real values. + +## Rationale + +### Breaking the ERC-20 Compatibility + +The transparency inherent in ERC-20 tokens presents a significant issue for reusable blockchain identities. To address this, we prioritize privacy over ERC-20 compatibility, ensuring the confidentiality of token balances. + +### Reorg Oracles + +The trusted oracles and the minimum number of required signatures can be configured to achieve the desired level of decentralization. + +The basket holder proposes the input and output baskets for the reorg, while the oracles are responsible for verifying that the sums of the values on both sides (input and output) are equal. This system allows for mutual control, ensuring that no single party can manipulate the process. + +Fraudulent oracles can be tracked back on-chain, i.e., the system ensures weak-integrity at minimum. + +To further strengthen the integrity, it would also be possible to apply Zero-Knowledge Proofs (ZKP) to provide reorg proofs, however, we have chosen to use oracles for efficiency and simplicity reasons. + +### Off-chain Data Storage + +We have chosen the token operator, which in most cases will be the issuer or registrar, as the initial and main source for off-chain data. This is acceptable, since they must know anyway which investor holds which positions to manage lifecycle events on the token. While this approach may not be suitable for every use case within the broader Ethereum ecosystem, it fits well the financial instruments in the regulated environment of the financial industry, which rely on strict KYC and token operation procedures. + +## Backwards Compatibility + +* Opaque Token is not compatible with ERC-20 for reasons explained in the Rationale section. + +## Security Considerations + +### Fraudulent Oracles + + +### Oracles Collecting Confidential Data + + +### Confidential Data Loss + + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From 15b3279d43d2fc7afa31407d91737d9c9997256e Mon Sep 17 00:00:00 2001 From: Greg Marlin <35407723+marleymarl@users.noreply.github.com> Date: Mon, 14 Oct 2024 08:27:05 -0700 Subject: [PATCH 21/46] Add ERC: AI Agent NFTs Merged by EIP-Bot. --- ERCS/erc-7662.md | 106 ++++++++++++++++++++++++++ assets/erc-7662/ERC7662.sol | 148 ++++++++++++++++++++++++++++++++++++ 2 files changed, 254 insertions(+) create mode 100644 ERCS/erc-7662.md create mode 100644 assets/erc-7662/ERC7662.sol diff --git a/ERCS/erc-7662.md b/ERCS/erc-7662.md new file mode 100644 index 0000000000..252044e184 --- /dev/null +++ b/ERCS/erc-7662.md @@ -0,0 +1,106 @@ +--- +eip: 7662 +title: AI Agent NFTs +description: A specification for NFTs that represent AI Agents. +author: Greg Marlin (@marleymarl) +discussions-to: https://ethereum-magicians.org/t/erc-7662-ai-agent-nfts/19371 +status: Draft +type: Standards Track +category: ERC +created: 2024-03-26 +requires: 721 +--- + +## Abstract + +This proposal introduces a standard for AI agent NFTs. When AI Agents are created and traded as NFTs, it doesn't make sense to put the prompts in the token metadata, therefore it requires a standard custom struct. It also doesn't make sense to store the prompts directly onchain as they can be quite large, therefore this standard proposes they be stored as decentralized storage URLs. This standard also proposes two options on how this data should be made private to the owner of the NFT, with the favored implementation option being encrypting the data using custom contract parameters for decryption that decrypt only to the owner of the NFT. + +## Motivation + +The creation and trading of AI Agent NFTs are a natural fit and offer the potential for an entirely new onchain market. This requires some custom data to be embedded in the NFT through a custom struct and this needs to be standardized so that any marketplace or AI Agent management product, among others, know how to create and parse AI Agent NFTs. The goal of this standard is to provide a new utility for NFTs in the field of AI and also to provide new liquidity, through the NFT market, for AI Agents. If widely adopted by marketplaces, and infrastructure and no-code providers this should open up a new market and community for AI Agent creators in different fields, AI Agent consumers and NFT marketplaces. + + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + + +All ERC-XXXX compliant contracts MUST implement the standard [ERC-721](./eip-721.md) functionality for minting and transferring NFTs, and MUST additionally implement this standard's Agent interface + +```solidity + +interface IERC7662 is IERC721 { + + function getAgentData(uint256 tokenId) external view returns ( + string memory name, + string memory description, + string memory model, + string memory userPromptURI, + string memory systemPromptURI, + bool promptsEncrypted + ); + + event AgentUpdated(uint256 indexed tokenId); +} +``` + +and MUST implement the mapping between NFT Token ID and its Agent information. + +It is RECOMMENDED that this mapping is public and that the URIs for User Prompt and System Prompt are made private through encryption with decryption logic set to the holder of the NFT via custom contract parameters set during encryption, and the method or platform used to provide this encryption SHOULD be retrievable as a data property of the NFT in order that platforms that should facilitate the use of these NFTs can set up a predictable way to handle this decryption, depending on the platform or method used. + +It is conceivable to also create an implementation whereby this mapping was set to private and accessed through a custom function that restricted access to the holder of the NFT. This approach would explose the prompts through their urls though, therefore the RECOMMENDED approach is a public mapping and encryption on the URLs. This also has the benefit of publicly exposing the data in the Agent struct to verify name, description and model and that encyrpted URIs for the User Prompt and System Prompt exist. + +All ERC-XXXX compliant contracts MUST implement a function to mint new Agent tokens. This function SHOULD: + +- Accept parameters for all Agent properties (name, description, model, userPromptURI, systemPromptURI, etc.) +- Mint a new token to the specified recipient +- Associate the provided Agent properties with the newly minted token +- Emit an event signaling the creation of a new Agent token + +It is RECOMMENDED that ERC-XXXX compliant contracts provide functionality to encrypt the user prompt and system prompt. This functionality SHOULD: + +- Allow only the token owner to encrypt the prompts +- Update the userPromptURI and systemPromptURI with encrypted versions +- Set a flag indicating that the prompts are encrypted + +It is RECOMMENDED to implement the following event: + +```solidity +event AgentCreated(string name, string description, string model, address recipient, uint256 tokenId) + +``` + +This event SHOULD be emitted when a new Agent token is minted, providing key information about the newly created Agent. + +To enable dynamic variables being injected into the User Prompt before being run, any such variables MUST be surrounded with ${} e.g. ${dynamicVariableName} in order that they can be recognized and handled appropriately by programs and systems that will enabled the injection, e.g. web forms and automation systems. + +It is RECOMMENDED to add a data to the [ERC-721](./eip-721.md) standard that makes it easy for e.g. NFT Marketplaces to display data about the AI Agent NFT, i.e. Model, which in turn reveals the platform that is used for the agent, e.g. OpenAI in the case of gpt-4-0125-preview or Anthropic in the case of claude-3-opus-20240229. The standard name and description can be used to display the Agent Name and Agent Description. + +## Rationale + +This standard provides a unified way to create and parse AI Agent NFTs. + +This standard codifies the necessary parameters of Name, Description, Model, User Prompt, and System Prompt for creating and using AI Agent NFTs. + +It doesn't make practical sense to store the user and system prompts in an existing [ERC-721](./eip-721.md) as the only place to put would be in the token metadata that is open for anyone to access the prompts without owning the NFT. By storing the prompts in a custom Agent struct and restricting access to the prompts to the holder of the NFT. One way to do this would be through restricing access to the struct info to the holder of the NFT through a custom function, however since that option still exposes the prompt URIs to the public and thus the data inside them, the recommended method is by encrypting the prompts onchain and tying the decryption of the URLs to the holder of the NFT, using onchain services that enable decryption to be tied to contract parameters such as ownerOf(tokenId). + + +## Backwards Compatibility + +The AI Agents NFT standard introduces additional features and data to the standard [ERC-721](./eip-721.md) protocol, aimed at addressing the practical requirements of using NFTs to store, trade and use AI Agents. It is designed to be fully backward-compatible with the original [ERC-721](./eip-721.md) standard. All existing [ERC-721](./eip-721.md) functions (such as transferFrom, approve, and balanceOf) retain their original functionality and interfaces. Our extension does not modify these core behaviors, ensuring that any [ERC-721](./eip-721.md) compliant wallet or service can interact with these tokens without modifications. + +### Reference Implementation + +This is being currently implemented in a product for creating, managing and using AI Agents Onchain through a DApp interface. In this implementation, an encryption platform is being used to encrypt the prompts using custom EVMContractParameters that only decrypt for the holder of the NFT and using a decentralized storage network to store the URLs of this encrypted data. To facilitate that and make DApp handling easier, some parameters were added to Agent and the addEncryptedPrompts function is added that enables adding the encrypted prompt URIs after first minting the NFT (as the tokenId of the NFT is needed for setting the encryption/decryption conditions). + +A reference smart contract is provided in the assets folder. + + + +## Security Considerations + + + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). \ No newline at end of file diff --git a/assets/erc-7662/ERC7662.sol b/assets/erc-7662/ERC7662.sol new file mode 100644 index 0000000000..b6c0734e90 --- /dev/null +++ b/assets/erc-7662/ERC7662.sol @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; +import "@openzeppelin/contracts/interfaces/IERC721.sol"; +import "./lib/FactoryOperatorable.sol"; + +contract ERC7662 is FactoryOperatorable, ERC721URIStorage { + + uint256 public tokenIds; + + //NFT Base URI + string public baseURI; + + + struct Agent { + string name; + string description; + string model; + string userPromptURI; + string systemPromptURI; + string imageURI; + string category; + bool promptsEncrypted; + } + + mapping(address => uint256[]) public collectionIds; + mapping(uint => Agent) public Agents; + + event AgentCreated(string name, string description, string model, string category, address recipient, uint256 tokenId); + + constructor( + string memory collectionBaseURI, + address admin, + address operator) ERC721("Agent NFTs", "AGENTS") FactoryOperatorable(admin, operator) { + + baseURI = collectionBaseURI; + + } + + /** + * @dev Override supportInterface. + */ + function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721) returns (bool) { + return super.supportsInterface(interfaceId); + } + + + /** + * @dev Mint an Agent NFT and attach its data to the token id + * + * @param _recipient address to receive NFT + * @param _name string Name of the Agent + * @param _description string Description of the Agent + * @param _model string AI Model of the Agent + * @param _userPromptURI string URI of the Agent's User Prompt + * @param _systemPromptURI string URI of the Agent's System Prompt + * @param _imageURI string URI of the NFT image + * @param _category string Category of Agent + * @param _tokenURI string URI of the NFT + * + * Emits an AgentCreated event. + */ + function mintAgent(address _recipient, string memory _name, string memory _description, string memory _model, string memory _userPromptURI, string memory _systemPromptURI, string memory _imageURI, string memory _category, string memory _tokenURI) public { + tokenIds++; + bool _promptsEncrypted = false; + Agents[tokenIds] = Agent(_name, _description, _model, _userPromptURI, _systemPromptURI, _imageURI, _category, _promptsEncrypted); + + _mint(_recipient, tokenIds); + collectionIds[_recipient].push(tokenIds); + _setTokenURI(tokenIds, _tokenURI); + emit AgentCreated(_name, _description, _model, _category, _recipient, tokenIds); + } + + /** + * @dev Update NFT with Encrypted Prompts as token id needed first for encryption params + * + * @param _tokenId uint256 Id of the NFT to update + * @param _encryptedUserPromptURI string Encrypted URI of the Agent's User Prompt + * @param _encryptedSystemPromptURI string Encrypted URI of the Agent's System Prompt + */ + function addEncryptedPrompts(uint256 _tokenId, string memory _encryptedUserPromptURI, string memory _encryptedSystemPromptURI) public { + require(ownerOf(_tokenId) == msg.sender, "Sender must be token owner"); + Agent storage agent = Agents[_tokenId]; + agent.userPromptURI = _encryptedUserPromptURI; + agent.systemPromptURI = _encryptedSystemPromptURI; + agent.promptsEncrypted = true; + } + + /** + * @dev Return base URI + * Override {ERC721:_baseURI} + */ + function _baseURI() internal view override returns (string memory) { + return baseURI; + } + + /** + * @dev Return all token ids owned by address + * @param _address address Address to check for + */ + function getCollectionIds(address _address) public view returns (uint256[] memory) { + return collectionIds[_address]; + } + + + /** + * @dev Remove the given token from collectionIds. + * + * @param from address from + * @param tokenId tokenId to remove + */ + function _popId(address from, uint256 tokenId) internal { + uint256[] storage _collectionIds = collectionIds[from]; + for (uint256 i = 0; i < _collectionIds.length; i++) { + if (_collectionIds[i] == tokenId) { + if (i != _collectionIds.length - 1) { + _collectionIds[i] = _collectionIds[_collectionIds.length - 1]; + } + _collectionIds.pop(); + break; + } + } + } + + /** + * @dev Transfers `tokenId` from `from` to `to`. + * + * Requirements: + * + * - `tokenId` token must be owned by `from`. + * + * @param from address from + * @param to address to + * @param tokenId tokenId to transfer + */ + function _transfer( + address from, + address to, + uint256 tokenId + ) internal override { + super._transfer(from, to, tokenId); + _popId(from, tokenId); + collectionIds[to].push(tokenId); + } + + +} \ No newline at end of file From 7fa691ae15473276436935481ea6ab1806a14932 Mon Sep 17 00:00:00 2001 From: Suning Yao Date: Mon, 14 Oct 2024 08:29:16 -0700 Subject: [PATCH 22/46] Add ERC: Token with Metadata Merged by EIP-Bot. --- ERCS/erc-7729.md | 97 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 ERCS/erc-7729.md diff --git a/ERCS/erc-7729.md b/ERCS/erc-7729.md new file mode 100644 index 0000000000..d839b5b4d3 --- /dev/null +++ b/ERCS/erc-7729.md @@ -0,0 +1,97 @@ +--- +eip: 7729 +title: Token with Metadata +description: An ERC-20 extension for tokens with metadata. +author: msfew (@fewwwww) +discussions-to: https://ethereum-magicians.org/t/erc-7729-token-with-metadata/20939 +status: Draft +type: Standards Track +category: ERC +created: 2023-06-24 +requires: 20 +--- + +## Abstract + +This standard extends the [ERC-20](./eip-20.md) standard to include a `metadata` function interface and a JSON schema for metadata. + +## Motivation + +Memecoins have demonstrated the value of associating tokens with visual metadata. By standardizing a way to include metadata in ERC-20 tokens, developers can create more engaging and interactive tokens, fostering community engagement. + +## Specification + +The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +**Every compliant contract must implement the `IERC7729`, and [`ERC20`](./eip-20.md) interfaces.** + +This standard includes the following interface: + +```solidity +pragma solidity ^0.8.0; + +interface IERC20Metadata is IERC20 { + /// @dev Returns the metadata URI associated with the token. + /// The URI may point to a JSON file that conforms to the "ERCX Metadata JSON Schema". + function metadata() external view returns (string memory); +} +``` + +This is the "[ERC-7729](./eip-7729.md) Metadata JSON Schema" referenced above. + +```json +{ + "title": "Token Metadata", + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Identifies the asset to which this token represents" + }, + "description": { + "type": "string", + "description": "Describes the asset to which this token represents" + }, + "image": { + "type": "string", + "description": "A URI pointing to a resource with mime type image/* representing the asset to which this token represents." + } + } +} +``` + +## Rationale + +The `metadata` function was chosen based on existing implementations in standards and applications. + +## Backwards Compatibility + +This standard is backward compatible with the [ERC-20](./eip-20.md) as it extends the existing functionality with new interfaces. + +## Reference Implementation + +```solidity +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +interface IERC7729 is IERC20 { + function metadata() external view returns (string memory); +} + +contract ERC7729 is ERC20, IERCX { + string _metadata = "ipfs://QmakTsyRRmvihYwiAstYPYAeHBfaPYz3v9z2mkA1tYLA4w"; + + function metadata() external view returns (string memory) { + return _metadata; + } +} +``` + +## Security Considerations + +The metadata URI could be manipulated to point to malicious content or phishing sites. Off-chain indexers should perform validation checks to ensure the security and integrity of the metadata URIs for users. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From 32877d8832b4d510c39c80fe3f5160b4d34c3328 Mon Sep 17 00:00:00 2001 From: Jay Paik Date: Tue, 15 Oct 2024 17:17:13 -0400 Subject: [PATCH 23/46] Update ERC-6900: v0.8.0 release candidate Merged by EIP-Bot. --- ERCS/erc-6900.md | 793 ++++++++++-------- .../MSCA_Shared_Components_Diagram.svg | 2 +- assets/erc-6900/Modular_Account_Call_Flow.svg | 2 +- assets/erc-6900/Plugin_Execution_Flow.svg | 21 - 4 files changed, 433 insertions(+), 385 deletions(-) delete mode 100644 assets/erc-6900/Plugin_Execution_Flow.svg diff --git a/ERCS/erc-6900.md b/ERCS/erc-6900.md index 6cd2d28886..1cbc11d32f 100644 --- a/ERCS/erc-6900.md +++ b/ERCS/erc-6900.md @@ -1,19 +1,19 @@ --- eip: 6900 -title: Modular Smart Contract Accounts and Plugins -description: Interfaces for composable contract accounts optionally supporting upgradability and introspection -author: Adam Egyed (@adamegyed), Fangting Liu (@trinity-0111), Jay Paik (@jaypaik), Yoav Weiss (@yoavw), Huawei Gu (@huaweigu), Daniel Lim (@dlim-circle), Zhiyu Zhang (@ZhiyuCircle), Ruben Koch (@0xrubes), David Philipson (@dphilipson), Howy Ho (@howydev) +title: Modular Smart Contract Accounts +description: Interfaces for smart contract accounts and modules, optionally supporting upgradability and introspection +author: Adam Egyed (@adamegyed), Fangting Liu (@trinity-0111), Jay Paik (@jaypaik), Yoav Weiss (@yoavw), Huawei Gu (@huaweigu), Daniel Lim (@dlim-circle), Ruben Koch (@0xrubes), David Philipson (@dphilipson), Howy Ho (@howydev), Nikita Belenkov (@nikita-quantstamp), zer0dot (@zer0dot), David Kim (@PowerStream3604) discussions-to: https://ethereum-magicians.org/t/eip-modular-smart-contract-accounts-and-plugins/13885 status: Draft type: Standards Track category: ERC created: 2023-04-18 -requires: 165, 4337 +requires: 165, 1271, 4337 --- ## Abstract -This proposal standardizes smart contract accounts and account plugins, which are smart contract interfaces that allow for composable logic within smart contract accounts. This proposal is compliant with [ERC-4337](./eip-4337.md), and takes inspiration from [ERC-2535](./eip-2535.md) when defining interfaces for updating and querying modular function implementations. +This proposal standardizes smart contract accounts and account modules, which are smart contracts that allow for composable logic within smart contract accounts. This proposal is compliant with [ERC-4337](./eip-4337.md). This standard emphasizes secure permissioning of modules, and maximal interoperability between all spec-compliant accounts and modules. This modular approach splits account functionality into three categories, implements them in external contracts, and defines an expected execution flow from accounts. @@ -21,24 +21,17 @@ This modular approach splits account functionality into three categories, implem One of the goals that ERC-4337 accomplishes is abstracting the logic for execution and validation to each smart contract account. -Many new features of accounts can be built by customizing the logic that goes into the validation and execution steps. Examples of such features include session keys, subscriptions, spending limits, and role-based access control. Currently, some of these features are implemented natively by specific smart contract accounts, and others are able to be implemented by plugin systems. Examples of proprietary plugin systems include Safe modules and ZeroDev plugins. +Many new features of accounts can be built by customizing the logic that goes into the validation and execution steps. Examples of such features include session keys, subscriptions, spending limits, and role-based access control. Currently, some of these features are implemented natively by specific smart contract accounts, and others are able to be implemented by proprietary module systems like Safe modules. -However, managing multiple account instances provides a worse user experience, fragmenting accounts across supported features and security configurations. Additionally, it requires plugin developers to choose which platforms to support, causing either platform lock-in or duplicated development effort. +However, managing multiple account implementations provides a poor user experience, fragmenting accounts across supported features and security configurations. Additionally, it requires module developers to choose which platforms to support, causing either platform lock-in or duplicated development effort. -We propose a standard that coordinates the implementation work between plugin developers and wallet developers. This standard defines a modular smart contract account capable of supporting all standard-conformant plugins. This allows users to have greater portability of their data, and for plugin developers to not have to choose specific account implementations to support. +We propose a standard that coordinates the implementation work between module developers and account developers. This standard defines a modular smart contract account capable of supporting all standard-conformant modules. This allows users to have greater portability of their data, and for module developers to not have to choose specific account implementations to support. -![diagram showing relationship between accounts and plugins with modular functions](../assets/eip-6900/MSCA_Shared_Components_Diagram.svg) +![diagram showing relationship between accounts and modules with modular functions](../assets/eip-6900/MSCA_Shared_Components_Diagram.svg) -We take inspiration from ERC-2535's diamond pattern for routing execution based on function selectors, and create a similarly composable account. However, the standard does not require the multi-facet proxy pattern. +These modules can contain execution logic, validation functions, and hooks. Validation functions define the circumstances under which the smart contract account will approve actions taken on its behalf, while hooks allow for pre and post execution controls. -These plugins can contain execution logic, validation schemes, and hooks. Validation schemes define the circumstances under which the smart contract account will approve actions taken on its behalf, while hooks allow for pre- and post-execution controls. - -Accounts adopting this standard will support modular, upgradable execution and validation logic. Defining this as a standard for smart contract accounts will make plugins easier to develop securely and will allow for greater interoperability. - -Goals: - -- Provide standards for how validation, execution, and hook functions for smart contract accounts should be written. -- Provide standards for how compliant accounts should add, update, remove, and inspect plugins. +Accounts adopting this standard will support modular, upgradable execution and validation logic. Defining this as a standard for smart contract accounts will make modules easier to develop securely and will allow for greater interoperability. ## Specification @@ -48,105 +41,86 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S - An **account** (or **smart contract account, SCA**) is a smart contract that can be used to send transactions and hold digital assets. It implements the `IAccount` interface from ERC-4337. - A **modular account** (or **modular smart contract account, MSCA**) is an account that supports modular functions. There are three types of modular functions: - - **Validation functions** validate the caller's authenticity and authority to the account. - - **Execution functions** execute any custom logic allowed by the account. - - **Hooks** execute custom logic and checks before and/or after an execution function or validation function. -- A **validation function** is a function that validates authentication and authorization of a caller to the account. There are two types of validation functions: - - **User Operation Validation** functions handle calls to `validateUserOp` and check the validity of an ERC-4337 user operation. - - **Runtime Validation** functions run before an execution function when not called via a user operation, and enforce checks. Common checks include allowing execution only by an owner. -- An **execution function** is a smart contract function that defines the main execution step of a function for a modular account. -- The **standard execute** functions are two specific execute functions that are implemented natively by the modular account, and not on a plugin. These allow for open-ended execution. -- A **hook** is a smart contract function executed before or after another function, with the ability to modify state or cause the entire call to revert. There are four types of hooks: - - **Pre User Operation Validation Hook** functions run before user operation validation functions. These can enforce permissions on what actions a validation function may perform via user operations. - - **Pre Runtime Validation Hook** functions run before runtime validation functions. These can enforce permissions on what actions a validation function may perform via direct calls. - - **Pre Execution Hook** functions run before an execution function. They may optionally return data to be consumed by their related post execution hook functions. - - **Post Execution Hook** functions run after an execution function. They may optionally take returned data from their related pre execution hook functions. -- An **associated function** refers to either a validation function or a hook. -- A **native function** refers to a function implemented natively by the modular account, as opposed to a function added by a plugin. -- A **plugin** is a deployed smart contract that hosts any amount of the above three kinds of modular functions: execution functions, validation functions, or hooks. -- A plugin **manifest** is responsible for describing the execution functions, validation functions, and hooks that will be configured on the MSCA during installation, as well as the plugin’s metadata, dependency requirements, and permissions. + - **Validation functions** validate authorization on behalf of the account. + - **Execution functions** execute custom logic allowed by the account. + - **Hooks** execute custom logic and checks before and/or after an execution function or validation function. There are two types of hooks: + - **Validation hooks** run before a validation function. These can enforce permissions on actions authorized by a validation function. + - **Execution hooks** can run before and/or after an execution function. Execution hooks can be attached either to a specific execution function or a validation function. A pre execution hook may optionally return data to be consumed by a post execution hook. +- A **native function** refers to a function implemented by the modular account, as opposed to a function added by a module. +- A **module** is a deployed smart contract that hosts any amount of the above three kinds of modular functions. +- A module's **manifest** describes the execution functions, interface IDs, and hooks that should be installed on the account. ### Overview -A modular account handles two kinds of calls: either from the `Entrypoint` through ERC-4337, or through direct calls from externally owned accounts (EOAs) and other smart contracts. This standard supports both use cases. - -A call to the smart contract account can be broken down into the steps as shown in the diagram below. The validation steps validate if the caller is allowed to perform the call. The pre execution hook step can be used to do any pre execution checks or updates. It can also be used along with the post execution hook step to perform additional actions or verification. The execution step performs a defined task or collection of tasks. +A modular account handles two kinds of calls: either from the `EntryPoint` through ERC-4337, or through direct calls from externally owned accounts (EOAs) and other smart contracts. This standard supports both use cases. -![diagram showing call flow within an modular account](../assets/eip-6900/Modular_Account_Call_Flow.svg) +A call to the modular account can be broken down into the steps as shown in the diagram below. The validation steps validate if the caller is allowed to perform the call. The pre execution hook step can be used to do any pre execution checks or updates. It can also be used along with the post execution hook step to perform additional actions or verification. The execution step performs a defined task or collection of tasks. -The following diagram shows permitted plugin execution flows. During a plugin's execution step from the above diagram, the plugin may perform a "Plugin Execution Function", using either `executeFromPlugin` or `executeFromPluginExternal`. These can be used by plugins to execute using the account's context. +![diagram showing call flow within a modular account](../assets/eip-6900/Modular_Account_Call_Flow.svg) -- `executeFromPlugin` handles calls to other installed plugin's execution function on the modular account. -- `executeFromPluginExternal` handles calls to external addresses. - -![diagram showing a plugin execution flow](../assets/eip-6900/Plugin_Execution_Flow.svg) - -Each step is modular, supporting different implementations for each execution function, and composable, supporting multiple steps through hooks. Combined, these allow for open-ended programmable accounts. +Each step is modular, supporting different implementations, which allows for open-ended programmable accounts. ### Interfaces -**Modular Smart Contract Accounts** **MUST** implement - -- `IAccount.sol` from [ERC-4337](./eip-4337.md). -- `IPluginManager.sol` to support installing and uninstalling plugins. -- `IStandardExecutor.sol` to support open-ended execution. **Calls to plugins through this SHOULD revert.** -- `IPluginExecutor.sol` to support execution from plugins. **Calls to plugins through `executeFromPluginExternal` SHOULD revert.** - -**Modular Smart Contract Accounts** **MAY** implement +Modular accounts MUST implement: -- `IAccountLoupe.sol` to support visibility in plugin configuration on-chain. +- `IAccount.sol` and `IAccountExecute.sol` from [ERC-4337](./eip-4337.md). +- `IModularAccount.sol` to support module management and usage, and account identification. +- The function `isValidSignature` from [ERC-1271](./eip-1271.md) -**Plugins** **MUST** implement +Modular accounts MAY implement: -- `IPlugin.sol` described below and implement [ERC-165](./eip-165.md) for `IPlugin`. +- `IModularAccountView.sol` to support visibility in account states on-chain. +- [ERC-165](./eip-165.md) for interfaces installed from modules. -#### `IPluginManager.sol` +Modules MUST implement: -Plugin manager interface. Modular Smart Contract Accounts **MUST** implement this interface to support installing and uninstalling plugins. +- `IModule.sol` described below and implement ERC-165 for `IModule`. -```solidity -// Treats the first 20 bytes as an address, and the last byte as a function identifier. -type FunctionReference is bytes21; - -interface IPluginManager { - event PluginInstalled(address indexed plugin, bytes32 manifestHash, FunctionReference[] dependencies); - - event PluginUninstalled(address indexed plugin, bool indexed onUninstallSucceeded); - - /// @notice Install a plugin to the modular account. - /// @param plugin The plugin to install. - /// @param manifestHash The hash of the plugin manifest. - /// @param pluginInstallData Optional data to be decoded and used by the plugin to setup initial plugin data - /// for the modular account. - /// @param dependencies The dependencies of the plugin, as described in the manifest. Each FunctionReference - /// MUST be composed of an installed plugin's address and a function ID of its validation function. - function installPlugin( - address plugin, - bytes32 manifestHash, - bytes calldata pluginInstallData, - FunctionReference[] calldata dependencies - ) external; - - /// @notice Uninstall a plugin from the modular account. - /// @param plugin The plugin to uninstall. - /// @param config An optional, implementation-specific field that accounts may use to ensure consistency - /// guarantees. - /// @param pluginUninstallData Optional data to be decoded and used by the plugin to clear plugin data for the - /// modular account. - function uninstallPlugin(address plugin, bytes calldata config, bytes calldata pluginUninstallData) external; -} - -``` +Modules MAY implement any of the following module types: -#### `IStandardExecutor.sol` +- `IValidationModule` to support validation functions for the account. +- `IValidationHookModule` to support hooks for validation functions. +- `IExecutionModule` to support execution functions and their installations on the account. +- `IExecutionHookModule` to support pre & post execution hooks for execution functions. -Standard execute interface. Modular Smart Contract Accounts **MUST** implement this interface to support open-ended execution. +#### `IModularAccount.sol` -Standard execute functions SHOULD check whether the call's target implements the `IPlugin` interface via ERC-165. - -**If the target is a plugin, the call SHOULD revert.** This prevents accidental misconfiguration or misuse of plugins (both installed and uninstalled). +Module execution and management interface. Modular accounts MUST implement this interface to support installing and uninstalling modules, and open-ended execution. ```solidity +/// @dev A packed representation of a module function. +/// Consists of the following, left-aligned: +/// Module address: 20 bytes +/// Entity ID: 4 bytes +type ModuleEntity is bytes24; + +/// @dev A packed representation of a validation function and its associated flags. +/// Consists of the following, left-aligned: +/// Module address: 20 bytes +/// Entity ID: 4 bytes +/// Flags: 1 byte +/// +/// Validation flags layout: +/// 0b00000___ // unused +/// 0b_____A__ // isGlobal +/// 0b______B_ // isSignatureValidation +/// 0b_______C // isUserOpValidation +type ValidationConfig is bytes25; + +/// @dev A packed representation of a hook function and its associated flags. +/// Consists of the following, left-aligned: +/// Module address: 20 bytes +/// Entity ID: 4 bytes +/// Flags: 1 byte +/// +/// Hook flags layout: +/// 0b00000___ // unused +/// 0b_____A__ // hasPre (exec only) +/// 0b______B_ // hasPost (exec only) +/// 0b_______C // hook type (0 for exec, 1 for validation) +type HookConfig is bytes25; + struct Call { // The target address for the account to call. address target; @@ -156,393 +130,490 @@ struct Call { bytes data; } -interface IStandardExecutor { +interface IModularAccount { + event ExecutionInstalled(address indexed module, ExecutionManifest manifest); + event ExecutionUninstalled(address indexed module, bool onUninstallSucceeded, ExecutionManifest manifest); + event ValidationInstalled(address indexed module, uint32 indexed entityId); + event ValidationUninstalled(address indexed module, uint32 indexed entityId, bool onUninstallSucceeded); + /// @notice Standard execute method. - /// @dev If the target is a plugin, the call SHOULD revert. - /// @param target The target address for account to call. + /// @param target The target address for the account to call. /// @param value The value to send with the call. /// @param data The calldata for the call. /// @return The return data from the call. function execute(address target, uint256 value, bytes calldata data) external payable returns (bytes memory); /// @notice Standard executeBatch method. - /// @dev If the target is a plugin, the call SHOULD revert. If any of the calls revert, the entire batch MUST + /// @dev If the target is a module, the call SHOULD revert. If any of the calls revert, the entire batch MUST /// revert. /// @param calls The array of calls. /// @return An array containing the return data from the calls. function executeBatch(Call[] calldata calls) external payable returns (bytes[] memory); -} -``` - -#### `IPluginExecutor.sol` -Execution interface for calls made from plugins. Modular Smart Contract Accounts **MUST** implement this interface to support execution from plugins. + /// @notice Execute a call using the specified runtime validation. + /// @param data The calldata to send to the account. + /// @param authorization The authorization data to use for the call. The first 24 bytes is a ModuleEntity which + /// specifies which runtime validation to use, and the rest is sent as a parameter to runtime validation. + function executeWithRuntimeValidation(bytes calldata data, bytes calldata authorization) + external + payable + returns (bytes memory); -The `executeFromPluginExternal` function SHOULD check whether the call's target implements the `IPlugin` interface via ERC-165. + /// @notice Install a module to the modular account. + /// @param module The module to install. + /// @param manifest the manifest describing functions to install. + /// @param installData Optional data to be used by the account to handle the initial execution setup. Data encoding + /// is implementation-specific. + function installExecution( + address module, + ExecutionManifest calldata manifest, + bytes calldata installData + ) external; -**If the target of `executeFromPluginExternal` function is a plugin, the call SHOULD revert.** + /// @notice Uninstall a module from the modular account. + /// @param module The module to uninstall. + /// @param manifest the manifest describing functions to uninstall. + /// @param uninstallData Optional data to be used by the account to handle the execution uninstallation. Data + /// encoding is implementation-specific. + function uninstallExecution( + address module, + ExecutionManifest calldata manifest, + bytes calldata uninstallData + ) external; -This prevents accidental misconfiguration or misuse of plugins (both installed and uninstalled). Installed plugins MAY interact with other installed plugins via the `executeFromPlugin` function. + /// @notice Installs a validation function across a set of execution selectors, and optionally mark it as a + /// global validation function. + /// @dev This does not validate anything against the manifest - the caller must ensure validity. + /// @param validationConfig The validation function to install, along with configuration flags. + /// @param selectors The selectors to install the validation function for. + /// @param installData Optional data to be used by the account to handle the initial validation setup. Data + /// encoding is implementation-specific. + /// @param hooks Optional hooks to install and associate with the validation function. Data encoding is + /// implementation-specific. + function installValidation( + ValidationConfig validationConfig, + bytes4[] calldata selectors, + bytes calldata installData, + bytes[] calldata hooks + ) external; -```solidity -interface IPluginExecutor { - /// @notice Execute a call from a plugin through the account. - /// @dev Permissions must be granted to the calling plugin for the call to go through. - /// @param data The calldata to send to the account. - /// @return The return data from the call. - function executeFromPlugin(bytes calldata data) external payable returns (bytes memory); + /// @notice Uninstall a validation function from a set of execution selectors. + /// @param validationFunction The validation function to uninstall. + /// @param uninstallData Optional data to be used by the account to handle the validation uninstallation. Data + /// encoding is implementation-specific. + /// @param hookUninstallData Optional data to be used by the account to handle hook uninstallation. Data encoding + /// is implementation-specific. + function uninstallValidation( + ModuleEntity validationFunction, + bytes calldata uninstallData, + bytes[] calldata hookUninstallData + ) external; - /// @notice Execute a call from a plugin to a non-plugin address. - /// @dev If the target is a plugin, the call SHOULD revert. Permissions must be granted to the calling plugin - /// for the call to go through. - /// @param target The address to be called. - /// @param value The value to send with the call. - /// @param data The calldata to send to the target. - /// @return The return data from the call. - function executeFromPluginExternal(address target, uint256 value, bytes calldata data) - external - payable - returns (bytes memory); + /// @notice Return a unique identifier for the account implementation. + /// @dev This function MUST return a string in the format "vendor.account.semver". The vendor and account + /// names MUST NOT contain a period character. + /// @return The account ID. + function accountId() external view returns (string memory); } ``` -#### `IAccountLoupe.sol` +#### `IModularAccountView.sol` -Plugin inspection interface. Modular Smart Contract Accounts **MAY** implement this interface to support visibility in plugin configuration on-chain. +Module inspection interface. Modular accounts MAY implement this interface to support visibility in module configuration. ```solidity -interface IAccountLoupe { - /// @notice Config for an execution function, given a selector. - struct ExecutionFunctionConfig { - address plugin; - FunctionReference userOpValidationFunction; - FunctionReference runtimeValidationFunction; - } - - /// @notice Pre and post hooks for a given selector. - /// @dev It's possible for one of either `preExecHook` or `postExecHook` to be empty. - struct ExecutionHooks { - FunctionReference preExecHook; - FunctionReference postExecHook; - } - - /// @notice Get the validation functions and plugin address for a selector. - /// @dev If the selector is a native function, the plugin address will be the address of the account. - /// @param selector The selector to get the configuration for. - /// @return The configuration for this selector. - function getExecutionFunctionConfig(bytes4 selector) external view returns (ExecutionFunctionConfig memory); - - /// @notice Get the pre and post execution hooks for a selector. - /// @param selector The selector to get the hooks for. - /// @return The pre and post execution hooks for this selector. - function getExecutionHooks(bytes4 selector) external view returns (ExecutionHooks[] memory); - - /// @notice Get the pre user op and runtime validation hooks associated with a selector. - /// @param selector The selector to get the hooks for. - /// @return preUserOpValidationHooks The pre user op validation hooks for this selector. - /// @return preRuntimeValidationHooks The pre runtime validation hooks for this selector. - function getPreValidationHooks(bytes4 selector) +/// @dev Represents data associated with a specific function selector. +struct ExecutionDataView { + // The module that implements this execution function. + // If this is a native function, the address must remain address(0). + address module; + // Whether or not the function needs runtime validation, or can be called by anyone. The function can still be + // state changing if this flag is set to true. + // Note that even if this is set to true, user op validation will still be required, otherwise anyone could + // drain the account of native tokens by wasting gas. + bool skipRuntimeValidation; + // Whether or not a global validation function may be used to validate this function. + bool allowGlobalValidation; + // The execution hooks for this function selector. + HookConfig[] executionHooks; +} + +struct ValidationDataView { + // Whether or not this validation function can be used as a global validation function. + bool isGlobal; + // Whether or not this validation function is a signature validator. + bool isSignatureValidation; + // Whether or not this validation function is a user operation validation function. + bool isUserOpValidation; + // The validation hooks for this validation function. + HookConfig[] validationHooks; + // Execution hooks to run with this validation function. + HookConfig[] executionHooks; + // The set of selectors that may be validated by this validation function. + bytes4[] selectors; +} + +interface IModularAccountView { + /// @notice Get the execution data for a selector. + /// @dev If the selector is a native function, the module address will be the address of the account. + /// @param selector The selector to get the data for. + /// @return The execution data for this selector. + function getExecutionData(bytes4 selector) external view returns (ExecutionDataView memory); + + /// @notice Get the validation data for a validation function. + /// @dev If the selector is a native function, the module address will be the address of the account. + /// @param validationFunction The validation function to get the data for. + /// @return The validation data for this validation function. + function getValidationData(ModuleEntity validationFunction) external view - returns ( - FunctionReference[] memory preUserOpValidationHooks, - FunctionReference[] memory preRuntimeValidationHooks - ); - - /// @notice Get an array of all installed plugins. - /// @return The addresses of all installed plugins. - function getInstalledPlugins() external view returns (address[] memory); + returns (ValidationDataView memory); } ``` -#### `IPlugin.sol` +#### `IModule.sol` -Plugin interface. Plugins **MUST** implement this interface to support plugin management and interactions with MSCAs. +Module interface. Modules MUST implement this interface to support module management and interactions with [ERC-6900](./eip-6900.md) modular accounts. ```solidity -interface IPlugin { - /// @notice Initialize plugin data for the modular account. - /// @dev Called by the modular account during `installPlugin`. - /// @param data Optional bytes array to be decoded and used by the plugin to setup initial plugin data for the modular account. +interface IModule is IERC165 { + /// @notice Initialize module data for the modular account. + /// @dev Called by the modular account during `installExecution`. + /// @param data Optional bytes array to be decoded and used by the module to setup initial module data for the + /// modular account. function onInstall(bytes calldata data) external; - /// @notice Clear plugin data for the modular account. - /// @dev Called by the modular account during `uninstallPlugin`. - /// @param data Optional bytes array to be decoded and used by the plugin to clear plugin data for the modular account. + /// @notice Clear module data for the modular account. + /// @dev Called by the modular account during `uninstallExecution`. + /// @param data Optional bytes array to be decoded and used by the module to clear module data for the modular + /// account. function onUninstall(bytes calldata data) external; - /// @notice Run the pre user operation validation hook specified by the `functionId`. - /// @dev Pre user operation validation hooks MUST NOT return an authorizer value other than 0 or 1. - /// @param functionId An identifier that routes the call to different internal implementations, should there be more than one. - /// @param userOp The user operation. - /// @param userOpHash The user operation hash. - /// @return Packed validation data for validAfter (6 bytes), validUntil (6 bytes), and authorizer (20 bytes). - function preUserOpValidationHook(uint8 functionId, UserOperation memory userOp, bytes32 userOpHash) external returns (uint256); + /// @notice Return a unique identifier for the module. + /// @dev This function MUST return a string in the format "vendor.module.semver". The vendor and module + /// names MUST NOT contain a period character. + /// @return The module ID. + function moduleId() external view returns (string memory); +} +``` + +#### `IValidationModule.sol` + +Validation module interface. Modules MAY implement this interface to provide validation functions for the account. - /// @notice Run the user operation validationFunction specified by the `functionId`. - /// @param functionId An identifier that routes the call to different internal implementations, should there be - /// more than one. +```solidity +interface IValidationModule is IModule { + /// @notice Run the user operation validation function specified by the `entityId`. + /// @param entityId An identifier that routes the call to different internal implementations, should there + /// be more than one. /// @param userOp The user operation. /// @param userOpHash The user operation hash. /// @return Packed validation data for validAfter (6 bytes), validUntil (6 bytes), and authorizer (20 bytes). - function userOpValidationFunction(uint8 functionId, UserOperation calldata userOp, bytes32 userOpHash) + function validateUserOp(uint32 entityId, PackedUserOperation calldata userOp, bytes32 userOpHash) external returns (uint256); - /// @notice Run the pre runtime validation hook specified by the `functionId`. + /// @notice Run the runtime validation function specified by the `entityId`. /// @dev To indicate the entire call should revert, the function MUST revert. - /// @param functionId An identifier that routes the call to different internal implementations, should there be more than one. + /// @param account the account to validate for. + /// @param entityId An identifier that routes the call to different internal implementations, should there + /// be more than one. /// @param sender The caller address. /// @param value The call value. /// @param data The calldata sent. - function preRuntimeValidationHook(uint8 functionId, address sender, uint256 value, bytes calldata data) external; + /// @param authorization Additional data for the validation function to use. + function validateRuntime( + address account, + uint32 entityId, + address sender, + uint256 value, + bytes calldata data, + bytes calldata authorization + ) external; - /// @notice Run the runtime validationFunction specified by the `functionId`. + /// @notice Validates a signature using ERC-1271. /// @dev To indicate the entire call should revert, the function MUST revert. - /// @param functionId An identifier that routes the call to different internal implementations, should there be - /// more than one. - /// @param sender The caller address. - /// @param value The call value. - /// @param data The calldata sent. - function runtimeValidationFunction(uint8 functionId, address sender, uint256 value, bytes calldata data) - external; + /// @param account the account to validate for. + /// @param entityId An identifier that routes the call to different internal implementations, should there + /// be more than one. + /// @param sender the address that sent the ERC-1271 request to the smart account + /// @param hash the hash of the ERC-1271 request + /// @param signature the signature of the ERC-1271 request + /// @return The ERC-1271 `MAGIC_VALUE` if the signature is valid, or 0xFFFFFFFF if invalid. + function validateSignature( + address account, + uint32 entityId, + address sender, + bytes32 hash, + bytes calldata signature + ) external view returns (bytes4); +} +``` - /// @notice Run the pre execution hook specified by the `functionId`. +#### `IValidationHookModule.sol` + +Validation hook module interface. Modules MAY implement this interface to provide hooks for validation functions for the account. + +```solidity +interface IValidationHookModule is IModule { + /// @notice Run the pre user operation validation hook specified by the `entityId`. + /// @dev Pre user operation validation hooks MUST NOT return an authorizer value other than 0 or 1. + /// @param entityId An identifier that routes the call to different internal implementations, should there + /// be more than one. + /// @param userOp The user operation. + /// @param userOpHash The user operation hash. + /// @return Packed validation data for validAfter (6 bytes), validUntil (6 bytes), and authorizer (20 bytes). + function preUserOpValidationHook(uint32 entityId, PackedUserOperation calldata userOp, bytes32 userOpHash) + external + returns (uint256); + + /// @notice Run the pre runtime validation hook specified by the `entityId`. /// @dev To indicate the entire call should revert, the function MUST revert. - /// @param functionId An identifier that routes the call to different internal implementations, should there be more than one. + /// @param entityId An identifier that routes the call to different internal implementations, should there + /// be more than one. /// @param sender The caller address. /// @param value The call value. /// @param data The calldata sent. - /// @return Context to pass to a post execution hook, if present. An empty bytes array MAY be returned. - function preExecutionHook(uint8 functionId, address sender, uint256 value, bytes calldata data) external returns (bytes memory); - - /// @notice Run the post execution hook specified by the `functionId`. - /// @dev To indicate the entire call should revert, the function MUST revert. - /// @param functionId An identifier that routes the call to different internal implementations, should there be more than one. - /// @param preExecHookData The context returned by its associated pre execution hook. - function postExecutionHook(uint8 functionId, bytes calldata preExecHookData) external; - - /// @notice Describe the contents and intended configuration of the plugin. - /// @dev This manifest MUST stay constant over time. - /// @return A manifest describing the contents and intended configuration of the plugin. - function pluginManifest() external pure returns (PluginManifest memory); + /// @param authorization Additional data for the hook to use. + function preRuntimeValidationHook( + uint32 entityId, + address sender, + uint256 value, + bytes calldata data, + bytes calldata authorization + ) external; - /// @notice Describe the metadata of the plugin. - /// @dev This metadata MUST stay constant over time. - /// @return A metadata struct describing the plugin. - function pluginMetadata() external pure returns (PluginMetadata memory); + /// @notice Run the pre signature validation hook specified by the `entityId`. + /// @dev To indicate the call should revert, the function MUST revert. + /// @param entityId An identifier that routes the call to different internal implementations, should there + /// be more than one. + /// @param sender The caller address. + /// @param hash The hash of the message being signed. + /// @param signature The signature of the message. + function preSignatureValidationHook(uint32 entityId, address sender, bytes32 hash, bytes calldata signature) + external + view; } ``` -### Plugin manifest +#### `IExecutionModule.sol` -The plugin manifest is responsible for describing the execution functions, validation functions, and hooks that will be configured on the MSCA during installation, as well as the plugin's metadata, dependencies, and permissions. +Execution module interface. Modules MAY implement this interface to provide execution functions for the account. ```solidity -enum ManifestAssociatedFunctionType { - // Function is not defined. - NONE, - // Function belongs to this plugin. - SELF, - // Function belongs to an external plugin provided as a dependency during plugin installation. Plugins MAY depend - // on external validation functions. It MUST NOT depend on external hooks, or installation will fail. - DEPENDENCY, - // Resolves to a magic value to always bypass runtime validation for a given function. - // This is only assignable on runtime validation functions. If it were to be used on a user op validationFunction, - // it would risk burning gas from the account. When used as a hook in any hook location, it is equivalent to not - // setting a hook and is therefore disallowed. - RUNTIME_VALIDATION_ALWAYS_ALLOW, - // Resolves to a magic value to always fail in a hook for a given function. - // This is only assignable to pre hooks (pre validation and pre execution). It should not be used on - // validation functions themselves, because this is equivalent to leaving the validation functions unset. - // It should not be used in post-exec hooks, because if it is known to always revert, that should happen - // as early as possible to save gas. - PRE_HOOK_ALWAYS_DENY -} - -/// @dev For functions of type `ManifestAssociatedFunctionType.DEPENDENCY`, the MSCA MUST find the plugin address -/// of the function at `dependencies[dependencyIndex]` during the call to `installPlugin(config)`. -struct ManifestFunction { - ManifestAssociatedFunctionType functionType; - uint8 functionId; - uint256 dependencyIndex; -} - -struct ManifestAssociatedFunction { +struct ManifestExecutionFunction { + // The selector to install bytes4 executionSelector; - ManifestFunction associatedFunction; + // If true, the function won't need runtime validation, and can be called by anyone. + bool skipRuntimeValidation; + // If true, the function can be validated by a global validation function. + bool allowGlobalValidation; } struct ManifestExecutionHook { - bytes4 selector; - ManifestFunction preExecHook; - ManifestFunction postExecHook; + bytes4 executionSelector; + uint32 entityId; + bool isPreHook; + bool isPostHook; } -struct ManifestExternalCallPermission { - address externalAddress; - bool permitAnySelector; - bytes4[] selectors; +/// @dev A struct describing how the module should be installed on a modular account. +struct ExecutionManifest { + // Execution functions defined in this module to be installed on the MSCA. + ManifestExecutionFunction[] executionFunctions; + ManifestExecutionHook[] executionHooks; + // List of ERC-165 interface IDs to add to account to support introspection checks. This MUST NOT include + // IModule's interface ID. + bytes4[] interfaceIds; } -struct SelectorPermission { - bytes4 functionSelector; - string permissionDescription; +interface IExecutionModule is IModule { + /// @notice Describe the contents and intended configuration of the module. + /// @dev This manifest MUST stay constant over time. + /// @return A manifest describing the contents and intended configuration of the module. + function executionManifest() external pure returns (ExecutionManifest memory); } +``` -/// @dev A struct holding fields to describe the plugin in a purely view context. Intended for front end clients. -struct PluginMetadata { - // A human-readable name of the plugin. - string name; - // The version of the plugin, following the semantic versioning scheme. - string version; - // The author field SHOULD be a username representing the identity of the user or organization - // that created this plugin. - string author; - // String descriptions of the relative sensitivity of specific functions. The selectors MUST be selectors for - // functions implemented by this plugin. - SelectorPermission[] permissionDescriptors; -} +#### `IExecutionHookModule.sol` -/// @dev A struct describing how the plugin should be installed on a modular account. -struct PluginManifest { - // List of ERC-165 interface IDs to add to account to support introspection checks. This MUST NOT include - // IPlugin's interface ID. - bytes4[] interfaceIds; - // If this plugin depends on other plugins' validation functions, the interface IDs of those plugins MUST be - // provided here, with its position in the array matching the `dependencyIndex` members of `ManifestFunction` - // structs used in the manifest. - bytes4[] dependencyInterfaceIds; - // Execution functions defined in this plugin to be installed on the MSCA. - bytes4[] executionFunctions; - // Plugin execution functions already installed on the MSCA that this plugin will be able to call. - bytes4[] permittedExecutionSelectors; - // Boolean to indicate whether the plugin can call any external address. - bool permitAnyExternalAddress; - // Boolean to indicate whether the plugin needs access to spend native tokens of the account. If false, the - // plugin MUST still be able to spend up to the balance that it sends to the account in the same call. - bool canSpendNativeToken; - ManifestExternalCallPermission[] permittedExternalCalls; - ManifestAssociatedFunction[] userOpValidationFunctions; - ManifestAssociatedFunction[] runtimeValidationFunctions; - ManifestAssociatedFunction[] preUserOpValidationHooks; - ManifestAssociatedFunction[] preRuntimeValidationHooks; - ManifestExecutionHook[] executionHooks; -} +Execution hook module interface. Modules MAY implement this interface to provide hooks for execution functions for the account. + +```solidity +interface IExecutionHookModule is IModule { + /// @notice Run the pre execution hook specified by the `entityId`. + /// @dev To indicate the entire call should revert, the function MUST revert. + /// @param entityId An identifier that routes the call to different internal implementations, should there + /// be more than one. + /// @param sender The caller address. + /// @param value The call value. + /// @param data The calldata sent. For `executeUserOp` calls, hook modules should receive the full msg.data. + /// @return Context to pass to a post execution hook, if present. An empty bytes array MAY be returned. + function preExecutionHook(uint32 entityId, address sender, uint256 value, bytes calldata data) + external + returns (bytes memory); + /// @notice Run the post execution hook specified by the `entityId`. + /// @dev To indicate the entire call should revert, the function MUST revert. + /// @param entityId An identifier that routes the call to different internal implementations, should there + /// be more than one. + /// @param preExecHookData The context returned by its associated pre execution hook. + function postExecutionHook(uint32 entityId, bytes calldata preExecHookData) external; +} ``` -### Expected behavior +### Validation Functions and Their Installation/Uninstallation + +- An account can have more than one validation module/function installed. +- An account can have the same validation module installed more than once. +- The entity ID of a validation function installed on an account MUST be unique. +- Validation installation MAY be deferred until a later time, such as upon first use. -#### Responsibilities of `StandardExecutor` and `PluginExecutor` +#### Installation -`StandardExecutor` functions are used for open-ended calls to external addresses. +During validation installation, the account MUST correctly set flags and other fields based on the incoming data provided by the user. -`PluginExecutor` functions are specifically used by plugins to request the account to execute with account's context. Explicit permissions are required for plugins to use `PluginExecutor`. +- The account MUST install all validation hooks specified by the user and SHOULD call `onInstall` with the user-provided data on the hook module to initialize state if specified by the user. +- The account MUST install all execution hooks specified by the user and SHOULD call `onInstall` with the user-provided data on the hook module to initialize state if specified by the user. +- The account MUST configure the validation function to validate all of the selectors specified by the user. +- The account MUST set all flags as specified, like `isGlobal`, `isSignatureValidation`, and `isUserOpValidation`. +- The account SHOULD call `onInstall` on the validation module to initialize state if specified by the user. +- The account MUST emit `ValidationInstalled` as defined in the interface for all installed validation functions. -The following behavior MUST be followed: +#### Uninstallation -- `StandardExecutor` can NOT call plugin execution functions and/or `PluginExecutor`. This is guaranteed by checking whether the call's target implements the `IPlugin` interface via ERC-165 as required. -- `StandardExecutor` can NOT be called by plugin execution functions and/or `PluginExecutor`. -- Plugin execution functions MUST NOT request access to `StandardExecutor`, they MAY request access to `PluginExecutor`. +During validation uninstallation, the account MUST correctly clear flags and other fields based on the incoming data provided by the user. -#### Calls to `installPlugin` +- The account MUST clear all flags for the validation function, like `isGlobal`, `isSignatureValidation`, and `isUserOpValidation`. +- The account MUST remove all hooks and SHOULD clear hook module states by calling `onUninstall` with the user-provided data for each hook, including both validation hooks and execution hooks, if specified by the user. + - The account MAY ignore the revert from `onUninstall` with try/catch depending on the design principle of the account. +- The account MUST clear the configuration for the selectors that the validation function can validate. +- The account SHOULD call `onUninstall` on the validation module to clean up state if specified by the user. +- The account MUST emit `ValidationUninstalled` as defined in the interface for all uninstalled validation functions. -The function `installPlugin` accepts 4 parameters: the address of the plugin to install, the Keccak-256 hash of the plugin's manifest, ABI-encoded data to pass to the plugin's `onInstall` callback, and an array of function references that represent the plugin's install dependencies. +### Execution Functions and Their Installation/Uninstallation -The function MUST retrieve the plugin's manifest by calling `pluginManifest()` using `staticcall`. +- An account can install any number of execution functions. +- An execution function selector MUST be unique in the account. +- An execution function selector MUST not conflict with native ERC-4337 and ERC-6900 functions. -The function MUST perform the following preliminary checks: +#### Installation -- Revert if the plugin has already been installed on the modular account. -- Revert if the plugin does not implement ERC-165 or does not support the `IPlugin` interface. -- Revert if `manifestHash` does not match the computed Keccak-256 hash of the plugin's returned manifest. This prevents installation of plugins that attempt to install a different plugin configuration than the one that was approved by the client. -- Revert if any address in `dependencies` does not support the interface at its matching index in the manifest's `dependencyInterfaceIds`, or if the two array lengths do not match, or if any of the dependencies are not already installed on the modular account. +During execution installation, the account MUST correctly set flags and other fields based on the incoming data and module manifest provided by the user. -The function MUST record the manifest hash and dependencies that were used for the plugin's installation. Each dependency's record MUST also be updated to reflect that it has a new dependent. These records MUST be used to ensure calls to `uninstallPlugin` are comprehensive and undo all edited configuration state from installation. The mechanism by which these records are stored and validated is up to the implementation. +- The account MUST install all execution functions and set flags and fields as specified in the manifest. +- The account MUST add all execution hooks as specified in the manifest. +- The account SHOULD add all supported interfaces as specified in the manifest. +- The account SHOULD call `onInstall` on the execution module to initialize state if specified by the user. +- The account MUST emit `ExecutionInstalled` as defined in the interface for all installed executions. -The function MUST store the plugin's permitted function selectors, permitted external calls, and whether it can spend the account's native tokens, to be able to validate calls to `executeFromPlugin` and `executeFromPluginExternal`. +#### Uninstallation -The function MUST parse through the execution functions, validation functions, and hooks in the manifest and add them to the modular account after resolving each `ManifestFunction` type. +During execution uninstallation, the account MUST correctly clear flags and other fields based on the incoming data and module manifest provided by the user. -- Each execution function selector MUST be added as a valid execution function on the modular account. If the function selector has already been added or matches the selector of a native function, the function SHOULD revert. -- If a validation function is to be added to a selector that already has that type of validation function, the function SHOULD revert. +- The account MUST remove all execution functions and clear flags and fields as specified in the manifest. +- The account MUST remove all execution hooks as specified in the manifest. +- The account SHOULD remove all supported interfaces as specified in the manifest. +- The account SHOULD call `onUninstall` on the execution module to clean up state and track call success if specified by the user. +- The account MUST emit `ExecutionUninstalled` as defined in the interface for all uninstalled executions. -The function MAY store the interface IDs provided in the manifest's `interfaceIds` and update its `supportsInterface` behavior accordingly. +### Hooks -Next, the function MUST call the plugin's `onInstall` callback with the data provided in the `pluginInstallData` parameter. This serves to initialize the plugin state for the modular account. If `onInstall` reverts, the `installPlugin` function MUST revert. +#### Execution Hooks Data Format -Finally, the function MUST emit the event `PluginInstalled` with the plugin's address, the hash of its manifest, and the dependencies that were used. +For accounts that implement execution hooks, accounts MUST conform to these execution hook formats: -> **⚠️ The ability to install and uninstall plugins is very powerful. The security of these functions determines the security of the account. It is critical for modular account implementers to make sure the implementation of the functions in `IPluginManager` have the proper security consideration and access control in place.** +1. For `executeUserOp` calls, for execution hooks associated with a validation function, accounts MUST send the full `msg.data`, including the `executeUserOp` selector. +2. For `executeUserOp` calls, for execution hooks associated with a selector, accounts MUST send `PackedUserOperation.callData` for `executeUserOp` calls, excluding `executeUserOp.selector` and the rest of the `PackedUserOperation`. +3. For `executeWithRuntimeValidation` calls, for all execution hooks, accounts MUST send the inner `data`. +4. For all other calls, for execution hooks associated with a selector, accounts MUST send over `msg.data`. -#### Calls to `uninstallPlugin` +#### Hook Execution Order -The function `uninstallPlugin` accepts 3 parameters: the address of the plugin to uninstall, a bytes field that may have custom requirements or uses by the implementing account, and ABI-encoded data to pass to the plugin's `onUninstall` callback. +It is RECOMMENDED that an account implementer runs hooks in first installed first executed order. However, an account MAY implement a different execution order. -The function MUST revert if the plugin is not installed on the modular account. +### Validation Call Flow -The function SHOULD perform the following checks: +Modular accounts support three different calls flows for validation: user op validation, runtime validation, and signature validation. User op validation happens within the account's implementation of the function `validateUserOp`, defined in the ERC-4337 interface `IAccount`. Runtime validation happens through the dispatcher function `executeWithRuntimeValidation`, or when using [direct call validation](#direct-call-validation). Signature validation happens within the account's implementation of the function `isValidSignature`, defined in ERC-1271. -- Revert if the hash of the manifest used at install time does not match the computed Keccak-256 hash of the plugin's current manifest. This prevents unclean removal of plugins that attempt to force a removal of a different plugin configuration than the one that was originally approved by the client for installation. To allow for removal of such plugins, the modular account MAY implement the capability for the manifest to be encoded in the config field as a parameter. -- Revert if there is at least 1 other installed plugin that depends on validation functions added by this plugin. Plugins used as dependencies SHOULD NOT be uninstalled while dependent plugins exist. +For each of these validation types, an account implementation MAY specify its own format for selecting which validation function to use, as well as any per-hook data for validation hooks. -The function SHOULD update account storage to reflect the uninstall via inspection functions, such as those defined by `IAccountLoupe`. Each dependency's record SHOULD also be updated to reflect that it has no longer has this plugin as a dependent. +Within the implementation of each type of validation function, the modular account MUST check that the provided validation function applies to the given function selector intended to be run (See [Checking Validation Applicability](#checking-validation-applicability)). Then, the account MUST execute all validation hooks of the corresponding type associated with the validation function in use. After the execution of validation hooks, the account MUST invoke the validation function of the corresponding type. If any of the validation hooks or the validation function reverts, the account MUST revert. It SHOULD include the module's revert data within its revert data. -The function MUST remove records for the plugin's manifest hash, dependencies, permitted function selectors, permitted external calls, and whether it can spend the account's native tokens. +The account MUST define a way to pass data separately for each validation hook and the validation function itself. This data MUST be sent as the `userOp.signature` field for user op validation, the `authorization` field for runtime validation, and the `signature` field for signature validation. -The function MUST parse through the execution functions, validation functions, and hooks in the manifest and remove them from the modular account after resolving each `ManifestFunction` type. If multiple plugins added the same hook, it MUST persist until the last plugin is uninstalled. +The result of user op validation SHOULD be the intersection of time bounds returned by the validation hooks and the validation function. If any validation hooks or the validation functions returns a value of `1` for the authorizer field, indicating a signature verification failure by the ERC-4337 standard, the account MUST return a value of `1` for the authorizer portion of the validation data. -If the account stored the interface IDs provided in the manifest's `interfaceIds` during installation, it MUST remove them and update its `supportsInterface` behavior accordingly. If multiple plugins added the same interface ID, it MUST persist until the last plugin is uninstalled. +The set of validation hooks run MUST be the hooks specified by account state at the start of validation. In other words, if the set of applicable hooks changes during validation, the original set of hooks MUST still run, and only future invocations of the same validation should reflect the changed set of hooks. -Next, the function MUST call the plugin's `onUninstall` callback with the data provided in the `pluginUninstallData` parameter. This serves to clear the plugin state for the modular account. If `onUninstall` reverts, execution SHOULD continue to allow the uninstall to complete. +#### Checking Validation Applicability -Finally, the function MUST emit the event `PluginUninstalled` with the plugin's address and whether the `onUninstall` callback succeeded. +To enforce module permission isolation, the modular account MUST check validation function applicability as part of each validation function implementation. -> **⚠️ Incorrectly uninstalled plugins can prevent uninstalls of their dependencies. Therefore, some form of validation that the uninstall step completely and correctly removes the plugin and its usage of dependencies is required.** +User op validation and runtime validation functions have a configurable range of applicability to functions on the account. This can be configured with selectors installed to a validation. Alternatively, a validation installation MAY specify the `isGlobal` flag as true, which means the account MUST consider it applicable to any module execution function with the `allowGlobalValidation` flag set to true, or for any account native function that the account MAY allow for global validation. -#### Calls to `validateUserOp` +If the selector being checked is `execute` or `executeBatch`, the modular account MUST perform additional checking. If the target of `execute` is the modular account's own address, or if the target of any `Call` within `executeBatch` is the account, validation MUST either revert or check that validation applies to the selector(s) being called. -When the function `validateUserOp` is called on modular account by the `EntryPoint`, it MUST find the user operation validation function associated to the function selector in the first four bytes of `userOp.callData`. If there is no function defined for the selector, or if `userOp.callData.length < 4`, then execution MUST revert. +Installed validation functions have two additional flag variables indicating what they may be used for. If a validation function is attempted to be used for user op validation and the flag `isUserOpValidation` is set to false, validation MUST revert. If the validation function is attempted to be used for signature validation and the flag `isSignatureValidation` is set to false, validation MUST revert. -If the function selector has associated pre user operation validation hooks, then those hooks MUST be run sequentially. If any revert, the outer call MUST revert. If any are set to `PRE_HOOK_ALWAYS_DENY`, the call MUST revert. If any return an `authorizer` value other than 0 or 1, execution MUST revert. If any return an `authorizer` value of 1, indicating an invalid signature, the returned validation data of the outer call MUST also be 1. If any return time-bounded validation by specifying either a `validUntil` or `validBefore` value, the resulting validation data MUST be the intersection of all time bounds provided. +#### Direct Call Validation -Then, the modular account MUST execute the validation function with the user operation and its hash as parameters using the `call` opcode. The returned validation data from the user operation validation function MUST be updated, if necessary, by the return values of any pre user operation validation hooks, then returned by `validateUserOp`. +If a validation function is installed with the entity ID of `0xffffffff`, it may be used as direct call validation. This occurs when a module or other address calls a function on the modular account, without wrapping its call in the dispatcher function `executeWithRuntimeValidation` to use as a selection mechanism for a runtime validation function. -#### Calls to execution functions +To implement direct call validation, the modular account MUST treat direct function calls that are not from the modular account itself or the `EntryPoint` as an attempt to validate using the caller's address and the entity ID of `0xffffffff`. If such a validation function is installed, and applies to the function intended to be called, the modular account MUST allow it to continue, without performing runtime validation. Any validation hooks and execution hooks installed to this validation function MUST still run. -When a function other than a native function is called on an modular account, it MUST find the plugin configuration for the corresponding selector added via plugin installation. If no corresponding plugin is found, the modular account MUST revert. Otherwise, the following steps MUST be performed. +### Execution Call Flow -Additionally, when the modular account natively implements functions in `IPluginManager` and `IStandardExecutor`, the same following steps MUST be performed for those functions. Other native functions MAY perform these steps. +For all non-view functions within `IModularAccount` except `executeWithRuntimeValidation`, all module-defined execution functions, and any additional native functions that the modular account MAY wish to include, the modular account MUST adhere to these steps during execution: -The steps to perform are: +If the caller is not the `EntryPoint` or the account, the account MUST check access control for direct call validation. -- If the call is not from the `EntryPoint`, then find an associated runtime validation function. If one does not exist, execution MUST revert. The modular account MUST execute all pre runtime validation hooks, then the runtime validation function, with the `call` opcode. All of these functions MUST receive the caller, value, and execution function's calldata as parameters. If any of these functions revert, execution MUST revert. If any pre runtime validation hooks are set to `PRE_HOOK_ALWAYS_DENY`, execution MUST revert. If the runtime validation function is set to `RUNTIME_VALIDATION_ALWAYS_ALLOW`, the validation function MUST be bypassed. -- If there are pre execution hooks defined for the execution function, execute those hooks with the caller, value, and execution function's calldata as parameters. If any of these hooks returns data, it MUST be preserved until the call to the post execution hook. The operation MUST be done with the `call` opcode. If there are duplicate pre execution hooks (i.e., hooks with identical `FunctionReference`s), run the hook only once. If any of these functions revert, execution MUST revert. -- Run the execution function. -- If any post execution hooks are defined, run the functions. If a pre execution hook returned data to the account, that data MUST be passed as a parameter to the associated post execution hook. The operation MUST be done with the `call` opcode. If there are duplicate post execution hooks, run them once for each unique associated pre execution hook. For post execution hooks without an associated pre execution hook, run the hook only once. If any of these functions revert, execution MUST revert. +Prior to running the target function, the modular account MUST run all pre execution hooks that apply for the current function call. Pre execution hooks apply if they have been installed to the currently running function selector, or if they are installed as an execution hook to the validation function that was used for the current execution. Pre execution hooks MUST run validation-associated hooks first, then selector-associated hooks second. -The set of hooks run for a given execution function MUST be the hooks specified by account state at the start of the execution phase. This is relevant for functions like `installPlugin` and `uninstallPlugin`, which modify the account state, and possibly other execution or native functions as well. +Next, the modular account MUST run the target function, either an account native function or a module-defined execution function. -#### Calls made from plugins +After the execution of the target function, the modular account MUST run any post execution hooks. These MUST be run in the reverse order of the pre execution hooks. If a hook is defined to be both a pre and a post execution hook, and the pre execution hook returned a non-empty `bytes` value to the account, the account MUST pass that data to the post execution hook. -Plugins MAY interact with other plugins and external addresses through the modular account using the functions defined in the `IPluginExecutor` interface. These functions MAY be called without a defined validation function, but the modular account MUST enforce these checks and behaviors: +The set of hooks run for a given target function MUST be the hooks specified by account state at the start of the execution phase. In other words, if the set of applicable hooks changes during execution, the original set of hooks MUST still run, and only future invocations of the same target function should reflect the changed set of hooks. -The `executeFromPlugin` function MUST allow plugins to call execution functions installed by plugins on the modular account. Hooks matching the function selector provided in `data` MUST be called. If the calling plugin's manifest did not include the provided function selector within `permittedExecutionSelectors` at the time of installation, execution MUST revert. +Module execution functions where the field `skipRuntimeValidation` is set to true, as well as native functions without access control, SHOULD omit the runtime validation step, including any runtime validation hooks. Native functions without access control MAY also omit running execution hooks. -The `executeFromPluginExternal` function MUST allow plugins to call external addresses as specified by its parameters on behalf of the modular account. If the calling plugin's manifest did not explicitly allow the external call within `permittedExternalCalls` at the time of installation, execution MUST revert. +### Extension + +#### Semi-Modular Account + +Account implementers MAY choose to design a semi-modular account, where certain features, such as default validation, are integrated into the core account. This approach SHOULD ensure compatibility with fully modular accounts, as defined in this proposal, to maintain interoperability across different implementations. ## Rationale ERC-4337 compatible accounts must implement the `IAccount` interface, which consists of only one method that bundles validation with execution: `validateUserOp`. A primary design rationale for this proposal is to extend the possible functions for a smart contract account beyond this single method by unbundling these and other functions, while retaining the benefits of account abstraction. -The function routing pattern of ERC-2535 is the logical starting point for achieving this extension into multi-functional accounts. It also meets our other primary design rationale of generalizing execution calls across multiple implementing contracts. However, a strict diamond pattern is constrained by its inability to customize validation schemes for specific execution functions in the context of `validateUserOp`, and its requirement of `delegatecall`. +This proposal includes several interfaces that build on ERC-4337. First, we standardize a set of modular functions that allow smart contract developers greater flexibility in bundling validation, execution, and hook logic. We also propose interfaces that provide methods for querying execution functions, validation functions, and hooks on a modular account. The rest of the interfaces describe a module's methods for exposing its modular functions and desired configuration, and the modular account's methods for installing and removing modules and allowing execution across modules and external addresses. + +### ERC-4337 Dependency -This proposal includes several interfaces that build on ERC-4337 and are inspired by ERC-2535. First, we standardize a set of modular functions that allow smart contract developers greater flexibility in bundling validation, execution, and hook logic. We also propose interfaces that take inspiration from the diamond standard and provide methods for querying execution functions, validation functions, and hooks on a modular account. The rest of the interfaces describe a plugin's methods for exposing its modular functions and desired configuration, and the modular account's methods for installing and removing plugins and allowing execution across plugins and external addresses. +ERC-6900's main objective is to create a secure and interoperable foundation through modular accounts and modules to increase the velocity and security of the smart account ecosystem, and ultimately the wallet ecosystem. Currently, the standard prescribes ERC-4337 for one of its [modular account call flows](#overview). However, this does not dictate that ERC-6900 will continue to be tied to ERC-4337. +It is likely that smart account builders will want to develop modular accounts that do not use ERC-4337 in the future (e.g., native account abstraction on rollups). Moreover, it is expected that ERC-4337 and its interfaces and contracts will continue to evolve until there is a protocol-level account abstraction. + +In the current state of the AA ecosystem, it is tough to predict the direction the builders and industry will take, so ERC-6900 will evolve together with the space's research, development, and adoption. The standard will do its best to address the objectives and create a secure foundation for modular accounts that may eventually be abstracted away from the infrastructure mechanism used. + +### Community Consensus + +While this standard has largely been the result of collaboration among the coauthors, there have been noteworthy contributions from others in the community with respect to improvements, education, and experimentation. Thank you to the contributors: + +- Gerard Persoon (@gpersoon) +- Harry Jeon (@sm-stack) +- Zhiyu Zhang (@ZhiyuCircle) +- Danilo Neves Cruz (@cruzdanilo) +- Iván Alberquilla (@ialberquilla) + +We host community calls and working groups to discuss standard improvements and invite anyone with questions or contributions into our discussion. ## Backwards Compatibility -No backward compatibility issues found. +Existing accounts that are deployed as proxies may have the ability to upgrade account implementations to one that supports this standard for modularity. Depending on implementation logic, existing modules may be wrapped in an adapter contract to adhere to the standard. + +The standard also allows for flexibility in account implementations, including accounts that have certain features implemented without modules, so usage of modules may be gradually introduced. ## Reference Implementation @@ -550,13 +621,11 @@ See `https://github.com/erc6900/reference-implementation` ## Security Considerations -The modular smart contract accounts themselves are trusted components. Installed plugins are trusted to varying degrees, as plugins can interact with an arbitrarily large or small set of resources on an account. For example, a wide-reaching malicious plugin could add reverting hooks to native function selectors, bricking the account, or add execution functions that may drain the funds of the account. However, it is also possible to install a plugin with a very narrow domain, and depend on the correctness of the account behavior to enforce its limited access. Users should therefore be careful in what plugins to add to their account. - -Users should perform careful due diligence before installing a plugin and should be mindful of the fact that plugins are potentially dangerous. The plugin's manifest can give users an understanding of the domain of the plugin, i.e., the requested permissions to install certain validation functions and/or hooks on certain execution selectors. Generally, plugins that include native function selectors in their domain, e.g., plugins that add a validation hook to the native `uninstallPlugin()` function, can introduce significantly more harm than plugins that simply add validation hooks to function selectors that the plugin itself is adding to the account. +The modular smart contract accounts themselves are trusted components. Installed modules are trusted to varying degrees, as modules can interact with an arbitrarily large or small set of resources on an account. For example, a wide-reaching malicious module could add reverting hooks to native function selectors, bricking the account, or add execution functions that may drain the funds of the account. However, it is also possible to install a module with a very narrow domain, and depend on the correctness of the account behavior to enforce its limited access. Users should therefore be careful in what modules to add to their account. -Plugins can also add validation hooks to function selectors installed by other plugins. While usually, such a plugin would, e.g., add additional pre-validation hooks, it can also cause the previously installed plugin to be executed in an unintended context. For example, if a plugin were to only be intended to operate in the user operation context, its plugin manifest might only define user operation validation functions. However, another plugin might add a passing runtime validation function to that function selector, causing, for example, a session key plugin to suddenly be executed in a runtime validation context, circumventing all the parameter-validation that would have happened during user operation validation and granting unrestricted access to all session keys. Therefore, it is strongly recommended to always add reverting validation hooks to the context the plugin is not intended to be executed in. This recommendation may change in the next iteration of the standard. +Users should perform careful due diligence before installing a module and should be mindful of the fact that modules are potentially dangerous. The module's manifest can give users an understanding of the potential risks they are exposed to for that particular module. For instance, a request to install certain validation functions and/or hooks on certain execution selectors could potentially be a vector for DOS. -It is worth mentioning that execution hooks have no awareness of other execution hooks being performed in the same function selector execution setting. Since execution hooks can perform state changes, this reveals an important security consideration: An execution hook can only assure that at the time of its own execution, certain conditions are met, but this can not be generalized to the entire pre-execution context of potentially multiple pre-execution hooks. For example, a pre-execution hook cannot be assured that the storage it performed validation upon does not get further updated in subsequent pre-execution hooks. Even an associated post-execution hook potentially repeating the validation cannot assure that the storage remains unmodified because a prior post-execution hook may have reset the state. As long as the requirements checked by a plugin as part of an execution hook are only modifiable by the plugin itself, this can be considered safe. +Execution hooks have no awareness of other execution hooks being performed in the same function selector execution setting. Since execution hooks can perform state changes, this reveals an important security consideration: An execution hook can only assure that at the time of its own execution, certain conditions are met, but this can not be generalized to the entire pre execution context of potentially multiple pre execution hooks. For example, a pre execution hook cannot be assured that the storage it performed validation upon does not get further updated in subsequent pre execution hooks. Even a post execution hook potentially repeating the validation cannot assure that the storage remains unmodified because a prior post execution hook may have reset the state. As long as the requirements checked by a module as part of an execution hook are only modifiable by the module itself, this can be considered safe. ## Copyright diff --git a/assets/erc-6900/MSCA_Shared_Components_Diagram.svg b/assets/erc-6900/MSCA_Shared_Components_Diagram.svg index 836a8ad980..e443dd5681 100644 --- a/assets/erc-6900/MSCA_Shared_Components_Diagram.svg +++ b/assets/erc-6900/MSCA_Shared_Components_Diagram.svg @@ -14,4 +14,4 @@ - Alice's MSCAUO / TxPluginHooksValidationExecutionPluginHooksValidationExecutionUO / TxBob's MSCA \ No newline at end of file + Alice's MSCAUO / TxModuleHooksValidationExecutionModuleHooksValidationExecutionUO / TxBob's MSCA \ No newline at end of file diff --git a/assets/erc-6900/Modular_Account_Call_Flow.svg b/assets/erc-6900/Modular_Account_Call_Flow.svg index c4112c335c..8d7f7611a0 100644 --- a/assets/erc-6900/Modular_Account_Call_Flow.svg +++ b/assets/erc-6900/Modular_Account_Call_Flow.svg @@ -14,4 +14,4 @@ - Direct Call1 validation2. Execution Modular Account validateUserOpPre User Operation Validation Hook(s)User Operation Validation FunctionPre Execution Hook(s)Native Function / (Plugin) Execution FunctionPost Execution Hook(s)EntryPointEOA / SCRuntime Validation FunctionModular Account Call FlowPre Runtime Validation Hook(s) \ No newline at end of file + Direct Call1 validation2. Execution Modular Account validateUserOpPre User Operation Validation Hook(s)User Operation Validation FunctionPre Execution Hook(s)Native Function / (Module) Execution FunctionPost Execution Hook(s)EntryPointEOA / SCRuntime Validation FunctionModular Account Call FlowPre Runtime Validation Hook(s) \ No newline at end of file diff --git a/assets/erc-6900/Plugin_Execution_Flow.svg b/assets/erc-6900/Plugin_Execution_Flow.svg deleted file mode 100644 index 3a94b512ed..0000000000 --- a/assets/erc-6900/Plugin_Execution_Flow.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - Permitted External Contracts & Methods executeFromPluginPre Execution Hook(s)Permitted Plugin Execution FunctionPost Execution Hook(s)PluginsPlugin Permission Check executeFromPluginExternal(Plugin) Execution Function1 calls plugin 2.2 calls external contracts through executeFromPluginExternalPlugin Permission CheckModular AccountPlugin Execution Flow2.1 calls other installed plugin through executeFromPluginPre executeFromPluginExternal Hook(s)Post executeFromPluginExternal Hook(s) \ No newline at end of file From f9f3ecbf2f57a66d332c50e6d376dbe578d7f3d1 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Wed, 16 Oct 2024 13:00:40 -0300 Subject: [PATCH 24/46] Fix site URL in Jekyll config (#676) --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index d93acf2d21..57536d8d80 100644 --- a/_config.yml +++ b/_config.yml @@ -18,7 +18,7 @@ description: >- Ethereum Improvement Proposals (EIPs) describe standards for the Ethereum platform, including core protocol specifications, client APIs, and contract standards. -url: "https://eips.ethereum.org" +url: "https://ercs.ethereum.org" github_username: ethereum repository: ethereum/EIPs From 96026d1a3e052e79feb1bbe36ff6a2217ad41b5a Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Wed, 16 Oct 2024 22:26:03 -0400 Subject: [PATCH 25/46] Bump setup-ruby to v1.196.0 (#677) --- .github/workflows/ci.yml | 2 +- .github/workflows/jekyll.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fcf12c4d61..bda74a5223 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,7 +65,7 @@ jobs: cd $GITHUB_WORKSPACE rm -rf ERCs - name: Setup Ruby - uses: ruby/setup-ruby@55283cc23133118229fd3f97f9336ee23a179fcf # v1.146.0 + uses: ruby/setup-ruby@f26937343756480a8cb3ae1f623b9c8d89ed6984 # v1.196.0 with: ruby-version: '3.1' # Not needed with a .ruby-version file bundler-cache: true # runs 'bundle install' and caches installed gems automatically diff --git a/.github/workflows/jekyll.yml b/.github/workflows/jekyll.yml index a646532c71..32baad23e7 100644 --- a/.github/workflows/jekyll.yml +++ b/.github/workflows/jekyll.yml @@ -34,7 +34,7 @@ jobs: - name: Checkout uses: actions/checkout@v3 - name: Setup Ruby - uses: ruby/setup-ruby@55283cc23133118229fd3f97f9336ee23a179fcf # v1.146.0 + uses: ruby/setup-ruby@f26937343756480a8cb3ae1f623b9c8d89ed6984 # v1.196.0 with: ruby-version: '3.1' # Not needed with a .ruby-version file bundler-cache: true # runs 'bundle install' and caches installed gems automatically From ffb8f312edaf85f0462cae9b3e3f3a603cc93d61 Mon Sep 17 00:00:00 2001 From: Riley Date: Sat, 19 Oct 2024 18:39:31 -0700 Subject: [PATCH 26/46] Update ERC-6909: ERC-6909 nits Merged by EIP-Bot. --- ERCS/erc-6909.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ERCS/erc-6909.md b/ERCS/erc-6909.md index 63d566397f..e51fb9926e 100644 --- a/ERCS/erc-6909.md +++ b/ERCS/erc-6909.md @@ -3,7 +3,7 @@ eip: 6909 title: Minimal Multi-Token Interface description: A minimal specification for managing multiple tokens by their id in a single contract. author: JT Riley (@jtriley-eth), Dillon (@d1ll0n), Sara (@snreynolds), Vectorized (@Vectorized), Neodaoist (@neodaoist) -discussions-to: https://ethereum-magicians.org/t/eip-6909-multi-token-standard/13891 +discussions-to: https://ethereum-magicians.org/t/erc-6909-multi-token-standard/13891 status: Review type: Standards Track category: ERC @@ -29,6 +29,8 @@ A hybrid allowance-operator permission scheme enables granular yet scalable cont The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. +Every [ERC-6909](./eip-6909.md) compliant contract must implement the [ERC-165](./eip-165.md) interface in addition to the following interface. + ### Definitions - infinite: The maximum value for a uint256 (`2 ** 256 - 1`). @@ -62,7 +64,7 @@ The total `amount` of a token `id` that an `owner` owns. #### `allowance` -The total `amount` of a token id that a spender is permitted to transfer on behalf of an owner. +The total `amount` of a token `id` that a `spender` is permitted to transfer on behalf of an `owner`. ```yaml - name: allowance @@ -315,7 +317,7 @@ The interface ID is `0x0f632fb3`. ##### name -The `name` of the contract. +The `name` for a token `id`. ```yaml - name: name @@ -333,7 +335,7 @@ The `name` of the contract. ##### symbol -The ticker `symbol` of the contract. +The ticker `symbol` for a token `id`. ```yaml - name: symbol @@ -373,7 +375,7 @@ The `amount` of decimals for a token `id`. ##### contractURI -The `URI` for a token `id`. +The `URI` for the contract. ```yaml - name: contractURI From 60569a1f8b57fea10340dc34602baf895a613daa Mon Sep 17 00:00:00 2001 From: James Brown Date: Wed, 23 Oct 2024 13:54:35 +0800 Subject: [PATCH 27/46] Website: Clarify spec and fix issues in associated assets Merged by EIP-Bot. --- ERCS/erc-7738.md | 26 +- .../DecentralisedRegistryPermissioned.sol | 9 - assets/erc-7738/contracts/IERC7738.sol | 4 - assets/erc-7738/hardhat.config.ts | 59 +- assets/erc-7738/package-lock.json | 16836 ++++++++-------- assets/erc-7738/package.json | 59 +- .../erc-7738/scripts/createRegistryEntry.ts | 43 + assets/erc-7738/scripts/deploy.ts | 14 +- assets/erc-7738/scripts/upgradeRegistry.ts | 2 +- .../test/DecentralisedRegistry.test.ts | 85 - .../test/PermissionedRegistry.test.ts | 75 - assets/erc-7738/tokenscript/onboard.html | 2 +- .../erc-7738/tokenscript/out/tokenscript.tsml | 2 +- 13 files changed, 8363 insertions(+), 8853 deletions(-) create mode 100644 assets/erc-7738/scripts/createRegistryEntry.ts diff --git a/ERCS/erc-7738.md b/ERCS/erc-7738.md index 235122fcf9..9921e864b2 100644 --- a/ERCS/erc-7738.md +++ b/ERCS/erc-7738.md @@ -16,7 +16,7 @@ This EIP provides a means to create a standard registry for locating executable ## Motivation -[ERC-5169](./eip-5169.md) provides a client script lookup method for contracts. This requires the contract to have implemented the `ERC-5169` interface at the time of construction (or allow an upgrade path). +[ERC-5169](./eip-5169.md) provides a client script lookup method for contracts. This requires the contract to have implemented the [ERC-5169](./eip-5169.md) interface at the time of construction (or allow an upgrade path). This proposal outlines a contract that can supply prototype and certified scripts. The contract would be a multichain singleton instance that would be deployed at identical addresses on supported chains. @@ -32,7 +32,7 @@ The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL N The contract MUST implement the `IERC7738` interface. The contract MUST emit the `ScriptUpdate` event when the script is updated. -The contract SHOULD order the `scriptURI` returned so that the `ERC-173` `owner()` of the contract's script entries are returned first (in the case of simple implementations the wallet will pick the first `scriptURI` returned). +The contract SHOULD order the `scriptURI` returned so that the [ERC-173](./eip-173.md) `owner()` of the contract's script entries are returned first (in the case of simple implementations the wallet will pick the first `scriptURI` returned). The contract SHOULD provide a means to page through entries if there are a large number of scriptURI entries. ```solidity @@ -59,10 +59,30 @@ This method allows contracts written without the [ERC-5169](./eip-5169.md) inter ## Test Cases -Instructions for test harness and deployment can be found in the [Asset folder](../assets/eip-7738/tests.md). +Test cases are included in [NFTRegistryTest.test.ts](../assets/eip-7738/test/NFTRegistryTest.test.ts). Contracts, deployment scripts and registry script can be found alongside the test script. + +Clone the repo and run: + +```shell +cd ../assets/eip-7738 +npm install --save-dev hardhat +npm install +npx hardhat test +``` ## Reference Implementation +The live implementation of the script registry is at `0x0077380bCDb2717C9640e892B9d5Ee02Bb5e0682` on several mainnet, L2 and testnet chains. To deploy scripts for use you can directly call the ```setScriptURI``` function: + +```solidity +function setScriptURI(address contractAddress, string[] memory newScriptURIs) +``` + +or use the bundled ethers script, ensuring to fill in the target contract address and scriptURI: + +[Create Registry Entry](../assets/eip-7738/scripts/createRegistryEntry.ts) + +### Simplified Implementation ```solidity import "@openzeppelin/contracts/access/Ownable.sol"; diff --git a/assets/erc-7738/contracts/DecentralisedRegistryPermissioned.sol b/assets/erc-7738/contracts/DecentralisedRegistryPermissioned.sol index d417f4a62c..9904140fb7 100644 --- a/assets/erc-7738/contracts/DecentralisedRegistryPermissioned.sol +++ b/assets/erc-7738/contracts/DecentralisedRegistryPermissioned.sol @@ -13,11 +13,6 @@ contract DecentralisedRegistryPermissioned is IERC7738 { mapping(address => ScriptEntry) private _scriptURIs; -<<<<<<< HEAD - uint256 ll = 0; - -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 event RegisterOwner( address indexed contractAddress, address indexed newOwner @@ -62,10 +57,6 @@ contract DecentralisedRegistryPermissioned is IERC7738 { ); emit RegisterOwner(contractAddress, sender); existingEntry.owner = sender; -<<<<<<< HEAD - ll++; -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 } function isDelegateOrOwner( diff --git a/assets/erc-7738/contracts/IERC7738.sol b/assets/erc-7738/contracts/IERC7738.sol index ce2cffce80..5e07656977 100644 --- a/assets/erc-7738/contracts/IERC7738.sol +++ b/assets/erc-7738/contracts/IERC7738.sol @@ -13,9 +13,5 @@ interface IERC7738 { /// @notice Update the scriptURI /// emits event ScriptUpdate(address indexed contractAddress, scriptURI memory newScriptURI); -<<<<<<< HEAD function setScriptURI(address contractAddress, string[] calldata scriptURIList) external; -======= - function setScriptURI(address contractAddress, string[] memory scriptURIList) external; ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 } \ No newline at end of file diff --git a/assets/erc-7738/hardhat.config.ts b/assets/erc-7738/hardhat.config.ts index 3ec8092630..886d942894 100644 --- a/assets/erc-7738/hardhat.config.ts +++ b/assets/erc-7738/hardhat.config.ts @@ -2,20 +2,14 @@ import "dotenv/config" import { HardhatUserConfig } from "hardhat/config" import "@nomicfoundation/hardhat-toolbox" import "hardhat-gas-reporter" +import "@nomicfoundation/hardhat-verify"; -<<<<<<< HEAD require('@openzeppelin/hardhat-upgrades'); -let { PRIVATE_KEY, INFURA_KEY, ETHERSCAN_API_KEY, PRIVATE_KEY2, POLYGONSCAN_API_KEY, BASESCAN_API_KEY } = process.env; +let { PRIVATE_KEY, INFURA_KEY, ETHERSCAN_API_KEY, PRIVATE_KEY2, POLYGONSCAN_API_KEY, BASESCAN_API_KEY, ARBITRUM_API_KEY, OPTIMISM_API_KEY } = process.env; const config: HardhatUserConfig = { solidity: { compilers: [{ version: "0.8.24" }, { version: "0.8.24" }], settings: { optimizer: { enabled: true, runs: 400} }}, -======= -let { PRIVATE_KEY, INFURA_KEY, ETHERSCAN_API_KEY } = process.env; - -const config: HardhatUserConfig = { - solidity: { compilers: [{ version: "0.8.24" }, { version: "0.8.24" }] }, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 networks: { mainnet: { url: `https://mainnet.infura.io/v3/${INFURA_KEY}`, @@ -25,7 +19,6 @@ const config: HardhatUserConfig = { url: `https://sepolia.infura.io/v3/${INFURA_KEY}`, accounts: [`${PRIVATE_KEY}`], }, -<<<<<<< HEAD holesky: { url: `https://ethereum-holesky-rpc.publicnode.com`, accounts: [`${PRIVATE_KEY}`], @@ -63,34 +56,50 @@ const config: HardhatUserConfig = { accounts: [`${PRIVATE_KEY}`] }, arbitrum: { - url: `https://arbitrum-mainnet.infura.io/v3/${INFURA_KEY}`, + url: `https://rpc.ankr.com/arbitrum`, accounts: [`${PRIVATE_KEY}`] }, arbitrumsepolia: { url: `https://arbitrum-sepolia.infura.io/v3/${INFURA_KEY}`, -======= - mumbai: { - url: `https://polygon-mumbai.infura.io/v3/${INFURA_KEY}`, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 accounts: [`${PRIVATE_KEY}`] }, hardhat: { gasPrice: 100000000000, -<<<<<<< HEAD allowUnlimitedContractSize: true, + }, + mint: { + url: `https://global.rpc.mintchain.io`, + accounts: [`${PRIVATE_KEY}`] + }, + mintsepolia: { + url: `https://sepolia-testnet-rpc.mintchain.io`, + accounts: [`${PRIVATE_KEY}`] + }, + optimism: { + url: `https://mainnet.optimism.io`, + accounts: [`${PRIVATE_KEY}`] } }, etherscan: { - //apiKey: `${ETHERSCAN_API_KEY}` //for contract verify https://holesky.infura.io/v3/${INFURA_KEY} - //apiKey: `${POLYGONSCAN_API_KEY}` //for verifying on Polygonscan powered chains - apiKey: `${BASESCAN_API_KEY}` -======= + apiKey: { + mint: "empty", + optimisticEthereum: `${OPTIMISM_API_KEY}`, + arbitrumOne: `${ARBITRUM_API_KEY}`, + mainnet: `${ETHERSCAN_API_KEY}`, + holesky: `${ETHERSCAN_API_KEY}`, + polygon: `${POLYGONSCAN_API_KEY}`, + base: `${BASESCAN_API_KEY}`, + }, + customChains: [ + { + network: "mint", + chainId: 185, + urls: { + apiURL: "https://explorer.mintchain.io/api", + browserURL: "https://explorer.mintchain.io:443" + } } - }, - etherscan: { - apiKey: `${ETHERSCAN_API_KEY}` //for contract verify ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - } -} + ] +}} export default config diff --git a/assets/erc-7738/package-lock.json b/assets/erc-7738/package-lock.json index eb2d0b1170..7d8f2be37e 100644 --- a/assets/erc-7738/package-lock.json +++ b/assets/erc-7738/package-lock.json @@ -1,8616 +1,8228 @@ { - "name": "hardhat", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "hardhat", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "@nomicfoundation/hardhat-ethers": "^3.0.6", - "@openzeppelin/contracts": "^5.0.2", -<<<<<<< HEAD - "@openzeppelin/contracts-upgradeable": "^5.0.2", - "@openzeppelin/hardhat-upgrades": "^3.2.1", - "@openzeppelin/upgrades-core": "^1.35.0", -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dotenv": "^16.4.5", - "ethers": "^6.13.1", - "hardhat": "^2.22.6", - "stl-contracts": "^2.5.1" - }, - "devDependencies": { - "@nomicfoundation/hardhat-ignition-ethers": "^0.15.5", -<<<<<<< HEAD - "@nomicfoundation/hardhat-toolbox": "^5.0.0", - "@nomiclabs/hardhat-etherscan": "^3.1.8" -======= - "@nomicfoundation/hardhat-toolbox": "^5.0.0" ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - } - }, - "node_modules/@adraffy/ens-normalize": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", - "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==" - }, -<<<<<<< HEAD - "node_modules/@aws-crypto/sha256-js": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-1.2.2.tgz", - "integrity": "sha512-Nr1QJIbW/afYYGzYvrF70LtaHrIRtd4TNAglX8BvlfxJLZ45SAmueIKYl5tWoNBPzp65ymXGFK0Bb1vZUpuc9g==", - "dependencies": { - "@aws-crypto/util": "^1.2.2", - "@aws-sdk/types": "^3.1.0", - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/sha256-js/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@aws-crypto/util": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-1.2.2.tgz", - "integrity": "sha512-H8PjG5WJ4wz0UXAFXeJjWCW1vkvIJ3qUUD+rGRwJ2/hj+xT58Qle2MTql/2MGzkU+1JLAFuR6aJpLAjHwhmwwg==", - "dependencies": { - "@aws-sdk/types": "^3.1.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/util/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@aws-sdk/types": { - "version": "3.609.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.609.0.tgz", - "integrity": "sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q==", - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/types/node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - }, - "node_modules/@aws-sdk/util-utf8-browser": { - "version": "3.259.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", - "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", - "dependencies": { - "tslib": "^2.3.1" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "devOptional": true, - "peer": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@ethereumjs/rlp": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", - "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", - "dev": true, - "peer": true, - "bin": { - "rlp": "bin/rlp" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@ethereumjs/util": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", - "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", - "dev": true, - "peer": true, - "dependencies": { - "@ethereumjs/rlp": "^4.0.1", - "ethereum-cryptography": "^2.0.0", - "micro-ftch": "^0.3.1" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@ethereumjs/util/node_modules/@noble/curves": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", - "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", - "dev": true, - "peer": true, - "dependencies": { - "@noble/hashes": "1.4.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@ethereumjs/util/node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@ethereumjs/util/node_modules/ethereum-cryptography": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", - "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", - "dev": true, - "peer": true, - "dependencies": { - "@noble/curves": "1.4.2", - "@noble/hashes": "1.4.0", - "@scure/bip32": "1.4.0", - "@scure/bip39": "1.3.0" - } - }, - "node_modules/@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" - } - }, - "node_modules/@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" - } - }, - "node_modules/@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0" - } - }, - "node_modules/@ethersproject/basex": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", - "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "peer": true, - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" - } - }, - "node_modules/@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0" - } - }, - "node_modules/@ethersproject/contracts": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", - "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "peer": true, - "dependencies": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0" - } - }, - "node_modules/@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "peer": true, - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "peer": true, - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "node_modules/@ethersproject/json-wallets/node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "dev": true, - "peer": true - }, - "node_modules/@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.0" - } - }, - "node_modules/@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ] - }, - "node_modules/@ethersproject/networks": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", - "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "peer": true, - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" - } - }, - "node_modules/@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/providers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", - "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "peer": true, - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "node_modules/@ethersproject/providers/node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@ethersproject/random": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", - "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "peer": true, - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/sha2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", - "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "peer": true, - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "peer": true, - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/transactions": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", - "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0" - } - }, - "node_modules/@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "peer": true, - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "peer": true, - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@ethersproject/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "peer": true, - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@fastify/busboy": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", - "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", - "engines": { - "node": ">=14" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "devOptional": true, - "peer": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "devOptional": true, - "peer": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "devOptional": true, - "peer": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@metamask/eth-sig-util": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", - "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", - "dependencies": { - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^6.2.1", - "ethjs-util": "^0.1.6", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.1" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@metamask/eth-sig-util/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@metamask/eth-sig-util/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/@metamask/eth-sig-util/node_modules/ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "node_modules/@noble/curves": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", - "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", - "dependencies": { - "@noble/hashes": "1.3.2" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/secp256k1": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", - "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "peer": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "peer": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nomicfoundation/edr": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.4.1.tgz", - "integrity": "sha512-NgrMo2rI9r28uidumvd+K2/AJLdxtXsUlJr3hj/pM6S1FCd/HiWaLeLa/cjCVPcE2u1rYAa3W6UFxLCB7S5Dhw==", - "dependencies": { - "@nomicfoundation/edr-darwin-arm64": "0.4.1", - "@nomicfoundation/edr-darwin-x64": "0.4.1", - "@nomicfoundation/edr-linux-arm64-gnu": "0.4.1", - "@nomicfoundation/edr-linux-arm64-musl": "0.4.1", - "@nomicfoundation/edr-linux-x64-gnu": "0.4.1", - "@nomicfoundation/edr-linux-x64-musl": "0.4.1", - "@nomicfoundation/edr-win32-x64-msvc": "0.4.1" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/@nomicfoundation/edr-darwin-arm64": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.4.1.tgz", - "integrity": "sha512-XuiUUnWAVNw7JYv7nRqDWfpBm21HOxCRBQ8lQnRnmiets9Ss2X5Ul9mvBheIPh/D0wBzwJ8TRtsSrorpwE79cA==", - "engines": { - "node": ">= 18" - } - }, - "node_modules/@nomicfoundation/edr-darwin-x64": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.4.1.tgz", - "integrity": "sha512-N1MfJqEX5ixaXlyyrHnaYxzwIT27Nc/jUgLI7ts4/9kRvPTvyZRYmXS1ciKhmUFr/WvFckTCix2RJbZoGGtX7g==", - "engines": { - "node": ">= 18" - } - }, - "node_modules/@nomicfoundation/edr-linux-arm64-gnu": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.4.1.tgz", - "integrity": "sha512-bSPOfmcFjJwDgWOV5kgZHeqg2OWu1cINrHSGjig0aVHehjcoX4Sgayrj6fyAxcOV5NQKA6WcyTFll6NrCxzWRA==", - "engines": { - "node": ">= 18" - } - }, - "node_modules/@nomicfoundation/edr-linux-arm64-musl": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.4.1.tgz", - "integrity": "sha512-F/+DgOdeBFQDrk+SX4aFffJFBgJfd75ZtE2mjcWNAh/qWiS7NfUxdQX/5OvNo/H6EY4a+3bZH6Bgzqg4mEWvMw==", - "engines": { - "node": ">= 18" - } - }, - "node_modules/@nomicfoundation/edr-linux-x64-gnu": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.4.1.tgz", - "integrity": "sha512-POHhTWczIXCPhzKtY0Vt/l+VCqqCx5gNR5ErwSrNnLz/arfQobZFAU+nc61BX3Jch82TW8b3AbfGI73Kh7gO0w==", - "engines": { - "node": ">= 18" - } - }, - "node_modules/@nomicfoundation/edr-linux-x64-musl": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.4.1.tgz", - "integrity": "sha512-uu8oNp4Ozg3H1x1We0FF+rwXfFiAvsOm5GQ+OBx9YYOXnfDPWqguQfGIkhrti9GD0iYhfQ/WOG5wvp0IzzgGSg==", - "engines": { - "node": ">= 18" - } - }, - "node_modules/@nomicfoundation/edr-win32-x64-msvc": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.4.1.tgz", - "integrity": "sha512-PaZHFw455z89ZiKYNTnKu+/TiVZVRI+mRJsbRTe2N0VlYfUBS1o2gdXBM12oP1t198HR7xQwEPPAslTFxGBqHA==", - "engines": { - "node": ">= 18" - } - }, - "node_modules/@nomicfoundation/ethereumjs-common": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz", - "integrity": "sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==", - "dependencies": { - "@nomicfoundation/ethereumjs-util": "9.0.4" - } - }, - "node_modules/@nomicfoundation/ethereumjs-rlp": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz", - "integrity": "sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==", - "bin": { - "rlp": "bin/rlp.cjs" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@nomicfoundation/ethereumjs-tx": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz", - "integrity": "sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==", - "dependencies": { - "@nomicfoundation/ethereumjs-common": "4.0.4", - "@nomicfoundation/ethereumjs-rlp": "5.0.4", - "@nomicfoundation/ethereumjs-util": "9.0.4", - "ethereum-cryptography": "0.1.3" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "c-kzg": "^2.1.2" - }, - "peerDependenciesMeta": { - "c-kzg": { - "optional": true - } - } - }, - "node_modules/@nomicfoundation/ethereumjs-util": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz", - "integrity": "sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==", - "dependencies": { - "@nomicfoundation/ethereumjs-rlp": "5.0.4", - "ethereum-cryptography": "0.1.3" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "c-kzg": "^2.1.2" - }, - "peerDependenciesMeta": { - "c-kzg": { - "optional": true - } - } - }, - "node_modules/@nomicfoundation/hardhat-chai-matchers": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.7.tgz", - "integrity": "sha512-RQfsiTwdf0SP+DtuNYvm4921X6VirCQq0Xyh+mnuGlTwEFSPZ/o27oQC+l+3Y/l48DDU7+ZcYBR+Fp+Rp94LfQ==", - "dev": true, - "peer": true, - "dependencies": { - "@types/chai-as-promised": "^7.1.3", - "chai-as-promised": "^7.1.1", - "deep-eql": "^4.0.1", - "ordinal": "^1.0.3" - }, - "peerDependencies": { - "@nomicfoundation/hardhat-ethers": "^3.0.0", - "chai": "^4.2.0", - "ethers": "^6.1.0", - "hardhat": "^2.9.4" - } - }, - "node_modules/@nomicfoundation/hardhat-ethers": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.6.tgz", - "integrity": "sha512-/xzkFQAaHQhmIAYOQmvHBPwL+NkwLzT9gRZBsgWUYeV+E6pzXsBQsHfRYbAZ3XEYare+T7S+5Tg/1KDJgepSkA==", - "dependencies": { - "debug": "^4.1.1", - "lodash.isequal": "^4.5.0" - }, - "peerDependencies": { - "ethers": "^6.1.0", - "hardhat": "^2.0.0" - } - }, - "node_modules/@nomicfoundation/hardhat-ignition": { - "version": "0.15.5", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition/-/hardhat-ignition-0.15.5.tgz", - "integrity": "sha512-Y5nhFXFqt4owA6Ooag8ZBFDF2RAZElMXViknVIsi3m45pbQimS50ti6FU8HxfRkDnBARa40CIn7UGV0hrelzDw==", - "dev": true, - "peer": true, - "dependencies": { - "@nomicfoundation/ignition-core": "^0.15.5", - "@nomicfoundation/ignition-ui": "^0.15.5", - "chalk": "^4.0.0", - "debug": "^4.3.2", - "fs-extra": "^10.0.0", - "prompts": "^2.4.2" - }, - "peerDependencies": { - "@nomicfoundation/hardhat-verify": "^2.0.1", - "hardhat": "^2.18.0" - } - }, - "node_modules/@nomicfoundation/hardhat-ignition-ethers": { - "version": "0.15.5", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition-ethers/-/hardhat-ignition-ethers-0.15.5.tgz", - "integrity": "sha512-W6s1QN9CFxzSVZS6w9Jcj3WLaK32z2FP5MxNU2OKY1Fn9ZzLr+miXbUbWYuRHl6dxrrl6sE8cv33Cybv19pmCg==", - "dev": true, - "peerDependencies": { - "@nomicfoundation/hardhat-ethers": "^3.0.4", - "@nomicfoundation/hardhat-ignition": "^0.15.5", - "@nomicfoundation/ignition-core": "^0.15.5", - "ethers": "^6.7.0", - "hardhat": "^2.18.0" - } - }, - "node_modules/@nomicfoundation/hardhat-network-helpers": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.11.tgz", - "integrity": "sha512-uGPL7QSKvxrHRU69dx8jzoBvuztlLCtyFsbgfXIwIjnO3dqZRz2GNMHJoO3C3dIiUNM6jdNF4AUnoQKDscdYrA==", - "dev": true, - "peer": true, - "dependencies": { - "ethereumjs-util": "^7.1.4" - }, - "peerDependencies": { - "hardhat": "^2.9.5" - } - }, - "node_modules/@nomicfoundation/hardhat-toolbox": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-5.0.0.tgz", - "integrity": "sha512-FnUtUC5PsakCbwiVNsqlXVIWG5JIb5CEZoSXbJUsEBun22Bivx2jhF1/q9iQbzuaGpJKFQyOhemPB2+XlEE6pQ==", - "dev": true, - "peerDependencies": { - "@nomicfoundation/hardhat-chai-matchers": "^2.0.0", - "@nomicfoundation/hardhat-ethers": "^3.0.0", - "@nomicfoundation/hardhat-ignition-ethers": "^0.15.0", - "@nomicfoundation/hardhat-network-helpers": "^1.0.0", - "@nomicfoundation/hardhat-verify": "^2.0.0", - "@typechain/ethers-v6": "^0.5.0", - "@typechain/hardhat": "^9.0.0", - "@types/chai": "^4.2.0", - "@types/mocha": ">=9.1.0", - "@types/node": ">=18.0.0", - "chai": "^4.2.0", - "ethers": "^6.4.0", - "hardhat": "^2.11.0", - "hardhat-gas-reporter": "^1.0.8", - "solidity-coverage": "^0.8.1", - "ts-node": ">=8.0.0", - "typechain": "^8.3.0", - "typescript": ">=4.5.0" - } - }, - "node_modules/@nomicfoundation/hardhat-verify": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.8.tgz", - "integrity": "sha512-x/OYya7A2Kcz+3W/J78dyDHxr0ezU23DKTrRKfy5wDPCnePqnr79vm8EXqX3gYps6IjPBYyGPZ9K6E5BnrWx5Q==", -<<<<<<< HEAD - "devOptional": true, -======= - "dev": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "peer": true, - "dependencies": { - "@ethersproject/abi": "^5.1.2", - "@ethersproject/address": "^5.0.2", - "cbor": "^8.1.0", - "chalk": "^2.4.2", - "debug": "^4.1.1", - "lodash.clonedeep": "^4.5.0", - "semver": "^6.3.0", - "table": "^6.8.0", - "undici": "^5.14.0" - }, - "peerDependencies": { - "hardhat": "^2.0.4" - } - }, - "node_modules/@nomicfoundation/hardhat-verify/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", -<<<<<<< HEAD - "devOptional": true, -======= - "dev": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "peer": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nomicfoundation/hardhat-verify/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", -<<<<<<< HEAD - "devOptional": true, -======= - "dev": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "peer": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nomicfoundation/hardhat-verify/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", -<<<<<<< HEAD - "devOptional": true, -======= - "dev": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "peer": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@nomicfoundation/hardhat-verify/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", -<<<<<<< HEAD - "devOptional": true, -======= - "dev": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "peer": true - }, - "node_modules/@nomicfoundation/hardhat-verify/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", -<<<<<<< HEAD - "devOptional": true, -======= - "dev": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "peer": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@nomicfoundation/hardhat-verify/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", -<<<<<<< HEAD - "devOptional": true, -======= - "dev": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nomicfoundation/hardhat-verify/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", -<<<<<<< HEAD - "devOptional": true, -======= - "dev": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "peer": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nomicfoundation/ignition-core": { - "version": "0.15.5", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-core/-/ignition-core-0.15.5.tgz", - "integrity": "sha512-FgvuoIXhakRSP524JzNQ4BviyzBBKpsFaOWubPZ4XACLT4/7vGqlJ/7DIn0D2NL2anQ2qs98/BNBY9WccXUX1Q==", - "dev": true, - "peer": true, - "dependencies": { - "@ethersproject/address": "5.6.1", - "@nomicfoundation/solidity-analyzer": "^0.1.1", - "cbor": "^9.0.0", - "debug": "^4.3.2", - "ethers": "^6.7.0", - "fs-extra": "^10.0.0", - "immer": "10.0.2", - "lodash": "4.17.21", - "ndjson": "2.0.0" - } - }, - "node_modules/@nomicfoundation/ignition-core/node_modules/@ethersproject/address": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.1.tgz", - "integrity": "sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "peer": true, - "dependencies": { - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/keccak256": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/rlp": "^5.6.1" - } - }, - "node_modules/@nomicfoundation/ignition-core/node_modules/cbor": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-9.0.2.tgz", - "integrity": "sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==", - "dev": true, - "peer": true, - "dependencies": { - "nofilter": "^3.1.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@nomicfoundation/ignition-ui": { - "version": "0.15.5", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-ui/-/ignition-ui-0.15.5.tgz", - "integrity": "sha512-ZcE4rIn10qKahR4OqS8rl8NM2Fbg2QYiBXgMgj74ZI0++LlCcZgB5HyaBbX+lsnKHjTXtjYD3b+2mtg7jFbAMQ==", - "dev": true, - "peer": true - }, -<<<<<<< HEAD - "node_modules/@nomicfoundation/slang": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/slang/-/slang-0.15.1.tgz", - "integrity": "sha512-th7nxRWRXf583uHpWUCd8U7BYxIqJX2f3oZLff/mlPkqIr45pD2hLT/o00eCjrBIR8N7vybUULZg1CeThGNk7g==", - "dependencies": { - "@nomicfoundation/slang-darwin-arm64": "0.15.1", - "@nomicfoundation/slang-darwin-x64": "0.15.1", - "@nomicfoundation/slang-linux-arm64-gnu": "0.15.1", - "@nomicfoundation/slang-linux-arm64-musl": "0.15.1", - "@nomicfoundation/slang-linux-x64-gnu": "0.15.1", - "@nomicfoundation/slang-linux-x64-musl": "0.15.1", - "@nomicfoundation/slang-win32-arm64-msvc": "0.15.1", - "@nomicfoundation/slang-win32-ia32-msvc": "0.15.1", - "@nomicfoundation/slang-win32-x64-msvc": "0.15.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/slang-darwin-arm64": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-darwin-arm64/-/slang-darwin-arm64-0.15.1.tgz", - "integrity": "sha512-taPHlCUNNztQZJze9OlZFK9cZH8Ut4Ih4QJQo5CKebXx9vWOUtmSBfKv/M2P8hiV/iL7Q5sPwR7HY9uZYnb49Q==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/slang-darwin-x64": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-darwin-x64/-/slang-darwin-x64-0.15.1.tgz", - "integrity": "sha512-kgZh5KQe/UcbFqn1EpyrvBuT8E6I1kWSgGPtO25t90zAqFv23sMUPdn7wLpMjngkD+quIIgrzQGUtupS5YYEig==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/slang-linux-arm64-gnu": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-linux-arm64-gnu/-/slang-linux-arm64-gnu-0.15.1.tgz", - "integrity": "sha512-Iw8mepaccKRWllPU9l+hoe88LN9fScC0Px3nFeNQy26qk1ueO0tjovP1dhTvmGwHUxacOYPqhQTUn7Iu0oxNoQ==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/slang-linux-arm64-musl": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-linux-arm64-musl/-/slang-linux-arm64-musl-0.15.1.tgz", - "integrity": "sha512-zcesdQZwRgrT7ND+3TZUjRK/uGF20EfhEfCg8ZMhrb4Q7XaK1JvtHazIs03TV8Jcs30TPkEXks8Qi0Zdfy4RuA==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/slang-linux-x64-gnu": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-linux-x64-gnu/-/slang-linux-x64-gnu-0.15.1.tgz", - "integrity": "sha512-FSmAnzKm58TFIwx4r/wOZtqfDx0nI6AfvnOh8kLDF5OxpWW3r0q9fq8lyaUReg9C/ZgCZRBn+m5WGrNKCZcvPQ==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/slang-linux-x64-musl": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-linux-x64-musl/-/slang-linux-x64-musl-0.15.1.tgz", - "integrity": "sha512-hnoA/dgeHQ8aS0SReABYkxf0d/Q6DdaKsaYv6ev21wyQA7TROxT1X3nekECLGu1GYLML8pzvD9vyAMBRKOkkyg==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/slang-win32-arm64-msvc": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-win32-arm64-msvc/-/slang-win32-arm64-msvc-0.15.1.tgz", - "integrity": "sha512-2H0chHQ4uTh4l4UxN5fIVHR5mKaL5mfYTID6kxxxv2+KAh68EpYWwxLlkS5So90R2WcuPvFvTVKLm/uRo4h4dg==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/slang-win32-ia32-msvc": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-win32-ia32-msvc/-/slang-win32-ia32-msvc-0.15.1.tgz", - "integrity": "sha512-CVZWBnbpFlVBg/m7bsiw70jY3p9TGH9vxq0vLEEJ56yK+QPosxPrKMcADojtGjIOjWjPSZ+lCoo5ilnW0a249g==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/slang-win32-x64-msvc": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-win32-x64-msvc/-/slang-win32-x64-msvc-0.15.1.tgz", - "integrity": "sha512-cyER8M1fdBTzIfihy55d4LGGlN/eQxDqfRUTXgJf1VvNR98tRB0Q3nBfyh5PK2yP98B4lMt3RJYDqTQu+dOVDA==", - "engines": { - "node": ">= 10" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/@nomicfoundation/solidity-analyzer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.2.tgz", - "integrity": "sha512-q4n32/FNKIhQ3zQGGw5CvPF6GTvDCpYwIf7bEY/dZTZbgfDsHyjJwURxUJf3VQuuJj+fDIFl4+KkBVbw4Ef6jA==", - "engines": { - "node": ">= 12" - }, - "optionalDependencies": { - "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.2", - "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.2", - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.2", - "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.2", - "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.2", - "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.2", - "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.2" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.2.tgz", - "integrity": "sha512-JaqcWPDZENCvm++lFFGjrDd8mxtf+CtLd2MiXvMNTBD33dContTZ9TWETwNFwg7JTJT5Q9HEecH7FA+HTSsIUw==", - "optional": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-darwin-x64": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.2.tgz", - "integrity": "sha512-fZNmVztrSXC03e9RONBT+CiksSeYcxI1wlzqyr0L7hsQlK1fzV+f04g2JtQ1c/Fe74ZwdV6aQBdd6Uwl1052sw==", - "optional": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.2.tgz", - "integrity": "sha512-3d54oc+9ZVBuB6nbp8wHylk4xh0N0Gc+bk+/uJae+rUgbOBwQSfuGIbAZt1wBXs5REkSmynEGcqx6DutoK0tPA==", - "optional": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.2.tgz", - "integrity": "sha512-iDJfR2qf55vgsg7BtJa7iPiFAsYf2d0Tv/0B+vhtnI16+wfQeTbP7teookbGvAo0eJo7aLLm0xfS/GTkvHIucA==", - "optional": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.2.tgz", - "integrity": "sha512-9dlHMAt5/2cpWyuJ9fQNOUXFB/vgSFORg1jpjX1Mh9hJ/MfZXlDdHQ+DpFCs32Zk5pxRBb07yGvSHk9/fezL+g==", - "optional": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.2.tgz", - "integrity": "sha512-GzzVeeJob3lfrSlDKQw2bRJ8rBf6mEYaWY+gW0JnTDHINA0s2gPR4km5RLIj1xeZZOYz4zRw+AEeYgLRqB2NXg==", - "optional": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.2.tgz", - "integrity": "sha512-Fdjli4DCcFHb4Zgsz0uEJXZ2K7VEO+w5KVv7HmT7WO10iODdU9csC2az4jrhEsRtiR9Gfd74FlG0NYlw1BMdyA==", - "optional": true, - "engines": { - "node": ">= 12" - } - }, -<<<<<<< HEAD - "node_modules/@nomiclabs/hardhat-etherscan": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.8.tgz", - "integrity": "sha512-v5F6IzQhrsjHh6kQz4uNrym49brK9K5bYCq2zQZ729RYRaifI9hHbtmK+KkIVevfhut7huQFEQ77JLRMAzWYjQ==", - "deprecated": "The @nomiclabs/hardhat-etherscan package is deprecated, please use @nomicfoundation/hardhat-verify instead", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.1.2", - "@ethersproject/address": "^5.0.2", - "cbor": "^8.1.0", - "chalk": "^2.4.2", - "debug": "^4.1.1", - "fs-extra": "^7.0.1", - "lodash": "^4.17.11", - "semver": "^6.3.0", - "table": "^6.8.0", - "undici": "^5.14.0" - }, - "peerDependencies": { - "hardhat": "^2.0.4" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/@openzeppelin/contracts": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.0.2.tgz", - "integrity": "sha512-ytPc6eLGcHHnapAZ9S+5qsdomhjo6QBHTDRRBFfTxXIpsicMhVPouPgmUPebZZZGX7vt9USA+Z+0M0dSVtSUEA==" - }, -<<<<<<< HEAD - "node_modules/@openzeppelin/contracts-upgradeable": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.0.2.tgz", - "integrity": "sha512-0MmkHSHiW2NRFiT9/r5Lu4eJq5UJ4/tzlOgYXNAIj/ONkQTVnz22pLxDvp4C4uZ9he7ZFvGn3Driptn1/iU7tQ==", - "peerDependencies": { - "@openzeppelin/contracts": "5.0.2" - } - }, - "node_modules/@openzeppelin/defender-sdk-base-client": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-base-client/-/defender-sdk-base-client-1.14.3.tgz", - "integrity": "sha512-4yG9E8N1c/ZP2jNR+Ah19wi7SBKpauAV/VcYcm7rg1dltDbzbH/oZnnXJlymT7IfjTPXkKHW8TPsaqz3EjS7tA==", - "dependencies": { - "amazon-cognito-identity-js": "^6.3.6", - "async-retry": "^1.3.3" - } - }, - "node_modules/@openzeppelin/defender-sdk-deploy-client": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-deploy-client/-/defender-sdk-deploy-client-1.14.3.tgz", - "integrity": "sha512-51WIZJz251lndK7uQU4gBE0gBX+2ZNTgf+hemtJUEPCpHtkooBRFFMID3EPGMKXVqf872pU8K3Huu9PyYQu6bw==", - "dependencies": { - "@openzeppelin/defender-sdk-base-client": "1.14.3", - "axios": "^1.7.2", - "lodash": "^4.17.21" - } - }, - "node_modules/@openzeppelin/defender-sdk-network-client": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-network-client/-/defender-sdk-network-client-1.14.3.tgz", - "integrity": "sha512-qrJLs2ubKSwrhP0x4V2QOPhlc1q8TYnkAcvjvk34VXMS8lhY1cpXSGoxnTw3Mi+eCSE1xOzKWISLi1UAOQOJIw==", - "dependencies": { - "@openzeppelin/defender-sdk-base-client": "1.14.3", - "axios": "^1.7.2", - "lodash": "^4.17.21" - } - }, - "node_modules/@openzeppelin/hardhat-upgrades": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-3.2.1.tgz", - "integrity": "sha512-Zy5M3QhkzwGdpzQmk+xbWdYOGJWjoTvwbBKYLhctu9B91DoprlhDRaZUwCtunwTdynkTDGdVfGr0kIkvycyKjw==", - "dependencies": { - "@openzeppelin/defender-sdk-base-client": "^1.10.0", - "@openzeppelin/defender-sdk-deploy-client": "^1.10.0", - "@openzeppelin/defender-sdk-network-client": "^1.10.0", - "@openzeppelin/upgrades-core": "^1.35.0", - "chalk": "^4.1.0", - "debug": "^4.1.1", - "ethereumjs-util": "^7.1.5", - "proper-lockfile": "^4.1.1", - "undici": "^6.11.1" - }, - "bin": { - "migrate-oz-cli-project": "dist/scripts/migrate-oz-cli-project.js" - }, - "peerDependencies": { - "@nomicfoundation/hardhat-ethers": "^3.0.0", - "@nomicfoundation/hardhat-verify": "^2.0.0", - "ethers": "^6.6.0", - "hardhat": "^2.0.2" - }, - "peerDependenciesMeta": { - "@nomicfoundation/hardhat-verify": { - "optional": true - } - } - }, - "node_modules/@openzeppelin/hardhat-upgrades/node_modules/undici": { - "version": "6.19.5", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.5.tgz", - "integrity": "sha512-LryC15SWzqQsREHIOUybavaIHF5IoL0dJ9aWWxL/PgT1KfqAW5225FZpDUFlt9xiDMS2/S7DOKhFWA7RLksWdg==", - "engines": { - "node": ">=18.17" - } - }, - "node_modules/@openzeppelin/upgrades-core": { - "version": "1.35.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.35.0.tgz", - "integrity": "sha512-XwwhJyPxACQ7rMhKAPCL6rhTXhbeumeQ3opmurEsHg025vHnISHwTPHd5VxzmOwbMBIJ7em1lnRTu+J2/IUWFQ==", - "dependencies": { - "@nomicfoundation/slang": "^0.15.1", - "cbor": "^9.0.0", - "chalk": "^4.1.0", - "compare-versions": "^6.0.0", - "debug": "^4.1.1", - "ethereumjs-util": "^7.0.3", - "minimist": "^1.2.7", - "proper-lockfile": "^4.1.1", - "solidity-ast": "^0.4.51" - }, - "bin": { - "openzeppelin-upgrades-core": "dist/cli/cli.js" - } - }, - "node_modules/@openzeppelin/upgrades-core/node_modules/cbor": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-9.0.2.tgz", - "integrity": "sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==", - "dependencies": { - "nofilter": "^3.1.0" - }, - "engines": { - "node": ">=16" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/@scure/base": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.7.tgz", - "integrity": "sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g==", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip32": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", - "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", - "dev": true, - "peer": true, - "dependencies": { - "@noble/curves": "~1.4.0", - "@noble/hashes": "~1.4.0", - "@scure/base": "~1.1.6" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip32/node_modules/@noble/curves": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", - "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", - "dev": true, - "peer": true, - "dependencies": { - "@noble/hashes": "1.4.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip32/node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip39": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", - "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", - "dev": true, - "peer": true, - "dependencies": { - "@noble/hashes": "~1.4.0", - "@scure/base": "~1.1.6" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip39/node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@sentry/core": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", - "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", - "dependencies": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/core/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@sentry/hub": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", - "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", - "dependencies": { - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/hub/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@sentry/minimal": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", - "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", - "dependencies": { - "@sentry/hub": "5.30.0", - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/minimal/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@sentry/node": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", - "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", - "dependencies": { - "@sentry/core": "5.30.0", - "@sentry/hub": "5.30.0", - "@sentry/tracing": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "cookie": "^0.4.1", - "https-proxy-agent": "^5.0.0", - "lru_map": "^0.3.3", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/node/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@sentry/tracing": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", - "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", - "dependencies": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/tracing/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@sentry/types": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", - "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/utils": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", - "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", - "dependencies": { - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/utils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, -<<<<<<< HEAD - "node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/types/node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/@solidity-parser/parser": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.5.tgz", - "integrity": "sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==", - "dev": true, - "peer": true, - "dependencies": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "devOptional": true, - "peer": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "devOptional": true, - "peer": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "devOptional": true, - "peer": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "devOptional": true, - "peer": true - }, - "node_modules/@typechain/ethers-v6": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@typechain/ethers-v6/-/ethers-v6-0.5.1.tgz", - "integrity": "sha512-F+GklO8jBWlsaVV+9oHaPh5NJdd6rAKN4tklGfInX1Q7h0xPgVLP39Jl3eCulPB5qexI71ZFHwbljx4ZXNfouA==", - "dev": true, - "peer": true, - "dependencies": { - "lodash": "^4.17.15", - "ts-essentials": "^7.0.1" - }, - "peerDependencies": { - "ethers": "6.x", - "typechain": "^8.3.2", - "typescript": ">=4.7.0" - } - }, - "node_modules/@typechain/hardhat": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-9.1.0.tgz", - "integrity": "sha512-mtaUlzLlkqTlfPwB3FORdejqBskSnh+Jl8AIJGjXNAQfRQ4ofHADPl1+oU7Z3pAJzmZbUXII8MhOLQltcHgKnA==", - "dev": true, - "peer": true, - "dependencies": { - "fs-extra": "^9.1.0" - }, - "peerDependencies": { - "@typechain/ethers-v6": "^0.5.1", - "ethers": "^6.1.0", - "hardhat": "^2.9.9", - "typechain": "^8.3.2" - } - }, - "node_modules/@typechain/hardhat/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "peer": true, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@types/bn.js": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", - "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/chai": { - "version": "4.3.16", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", - "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==", - "dev": true, - "peer": true - }, - "node_modules/@types/chai-as-promised": { - "version": "7.1.8", - "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz", - "integrity": "sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==", - "dev": true, - "peer": true, - "dependencies": { - "@types/chai": "*" - } - }, - "node_modules/@types/concat-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", - "dev": true, - "peer": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/form-data": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", - "dev": true, - "peer": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "peer": true, - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "node_modules/@types/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==" - }, - "node_modules/@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true, - "peer": true - }, - "node_modules/@types/mocha": { - "version": "10.0.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.7.tgz", - "integrity": "sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==", - "dev": true, - "peer": true - }, - "node_modules/@types/node": { - "version": "20.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", - "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/prettier": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", - "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", - "dev": true, - "peer": true - }, - "node_modules/@types/qs": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", - "dev": true, - "peer": true - }, - "node_modules/@types/secp256k1": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", - "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", - "dev": true, - "peer": true - }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "devOptional": true, - "peer": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", - "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", - "devOptional": true, - "peer": true, - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/adm-zip": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", - "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", - "engines": { - "node": ">=0.3.0" - } - }, - "node_modules/aes-js": { - "version": "4.0.0-beta.5", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", - "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==" - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", -<<<<<<< HEAD - "devOptional": true, -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dependencies": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, -<<<<<<< HEAD - "node_modules/amazon-cognito-identity-js": { - "version": "6.3.12", - "resolved": "https://registry.npmjs.org/amazon-cognito-identity-js/-/amazon-cognito-identity-js-6.3.12.tgz", - "integrity": "sha512-s7NKDZgx336cp+oDeUtB2ZzT8jWJp/v2LWuYl+LQtMEODe22RF1IJ4nRiDATp+rp1pTffCZcm44Quw4jx2bqNg==", - "dependencies": { - "@aws-crypto/sha256-js": "1.2.2", - "buffer": "4.9.2", - "fast-base64-decode": "^1.0.0", - "isomorphic-unfetch": "^3.0.0", - "js-cookie": "^2.2.1" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=0.4.2" - } - }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dependencies": { - "string-width": "^4.1.0" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/antlr4ts": { - "version": "0.5.0-alpha.4", - "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", - "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", - "dev": true, - "peer": true - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "devOptional": true, - "peer": true - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/array-back": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", - "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, -<<<<<<< HEAD - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, -<<<<<<< HEAD - "node_modules/array.prototype.findlast": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", - "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true, - "peer": true - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", -<<<<<<< HEAD - "devOptional": true, -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", - "dev": true, - "peer": true - }, -<<<<<<< HEAD - "node_modules/async-retry": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", - "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", - "dependencies": { - "retry": "0.13.1" - } - }, - "node_modules/async-retry/node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" -======= - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, - "peer": true ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 4.0.0" - } - }, -<<<<<<< HEAD - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/axios": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", - "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", -<<<<<<< HEAD -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, -<<<<<<< HEAD - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", - "dev": true, - "peer": true - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/blakejs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" - }, - "node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" - }, - "node_modules/boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", - "dependencies": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/boxen/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", - "dependencies": { - "base-x": "^3.0.2" - } - }, - "node_modules/bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "dependencies": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, -<<<<<<< HEAD - "node_modules/buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", -<<<<<<< HEAD -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true, - "peer": true - }, - "node_modules/cbor": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", - "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", -<<<<<<< HEAD - "devOptional": true, -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dependencies": { - "nofilter": "^3.1.0" - }, - "engines": { - "node": ">=12.19" - } - }, - "node_modules/chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", - "dev": true, - "peer": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chai-as-promised": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.2.tgz", - "integrity": "sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==", - "dev": true, - "peer": true, - "dependencies": { - "check-error": "^1.0.2" - }, - "peerDependencies": { - "chai": ">= 2.1.2 < 6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", - "dev": true, - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, - "peer": true, - "dependencies": { - "get-func-name": "^2.0.2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-table3": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", - "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", - "dev": true, - "peer": true, - "dependencies": { - "object-assign": "^4.1.0", - "string-width": "^2.1.1" - }, - "engines": { - "node": ">=6" - }, - "optionalDependencies": { - "colors": "^1.1.2" - } - }, - "node_modules/cli-table3/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/cli-table3/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/cli-table3/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "peer": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cli-table3/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", -<<<<<<< HEAD -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/command-exists": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", - "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==" - }, - "node_modules/command-line-args": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", - "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", - "dev": true, - "peer": true, - "dependencies": { - "array-back": "^3.1.0", - "find-replace": "^3.0.0", - "lodash.camelcase": "^4.3.0", - "typical": "^4.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/command-line-usage": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz", - "integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==", - "dev": true, - "peer": true, - "dependencies": { - "array-back": "^4.0.2", - "chalk": "^2.4.2", - "table-layout": "^1.0.2", - "typical": "^5.2.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/command-line-usage/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "peer": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/command-line-usage/node_modules/array-back": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", - "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/command-line-usage/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/command-line-usage/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "peer": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/command-line-usage/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "peer": true - }, - "node_modules/command-line-usage/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/command-line-usage/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/command-line-usage/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "peer": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/command-line-usage/node_modules/typical": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", - "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "engines": { - "node": ">= 12" - } - }, -<<<<<<< HEAD - "node_modules/compare-versions": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", - "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==" - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "peer": true, - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/concat-stream/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "peer": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/concat-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "peer": true - }, - "node_modules/concat-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "peer": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true, - "peer": true - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "devOptional": true, - "peer": true - }, - "node_modules/crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", - "dev": true, - "peer": true, - "engines": { - "node": "*" - } - }, -<<<<<<< HEAD - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/death": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", - "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", - "dev": true, - "peer": true - }, - "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-eql": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", - "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", - "dev": true, - "peer": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "peer": true - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", -<<<<<<< HEAD -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -<<<<<<< HEAD - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", -<<<<<<< HEAD -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/difflib": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", - "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", - "dev": true, - "peer": true, - "dependencies": { - "heap": ">= 0.2.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "peer": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dotenv": { - "version": "16.4.5", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/enquirer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", - "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", - "dependencies": { - "ansi-colors": "^4.1.1", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "engines": { - "node": ">=6" - } - }, -<<<<<<< HEAD - "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", -<<<<<<< HEAD -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", -<<<<<<< HEAD -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "engines": { - "node": ">= 0.4" - } - }, -<<<<<<< HEAD - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dependencies": { - "hasown": "^2.0.0" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", - "dev": true, - "peer": true, - "dependencies": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=0.12.0" - }, - "optionalDependencies": { - "source-map": "~0.2.0" - } - }, - "node_modules/esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", - "dev": true, - "peer": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eth-gas-reporter": { - "version": "0.2.27", - "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.27.tgz", - "integrity": "sha512-femhvoAM7wL0GcI8ozTdxfuBtBFJ9qsyIAsmKVjlWAHUbdnnXHt+lKzz/kmldM5lA9jLuNHGwuIxorNpLbR1Zw==", - "dev": true, - "peer": true, - "dependencies": { - "@solidity-parser/parser": "^0.14.0", - "axios": "^1.5.1", - "cli-table3": "^0.5.0", - "colors": "1.4.0", - "ethereum-cryptography": "^1.0.3", - "ethers": "^5.7.2", - "fs-readdir-recursive": "^1.1.0", - "lodash": "^4.17.14", - "markdown-table": "^1.1.3", - "mocha": "^10.2.0", - "req-cwd": "^2.0.0", - "sha1": "^1.1.1", - "sync-request": "^6.0.0" - }, - "peerDependencies": { - "@codechecks/client": "^0.1.0" - }, - "peerDependenciesMeta": { - "@codechecks/client": { - "optional": true - } - } - }, - "node_modules/eth-gas-reporter/node_modules/@noble/hashes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", - "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "peer": true - }, - "node_modules/eth-gas-reporter/node_modules/@scure/bip32": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", - "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "peer": true, - "dependencies": { - "@noble/hashes": "~1.2.0", - "@noble/secp256k1": "~1.7.0", - "@scure/base": "~1.1.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/@scure/bip39": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", - "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "peer": true, - "dependencies": { - "@noble/hashes": "~1.2.0", - "@scure/base": "~1.1.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/ethereum-cryptography": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", - "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", - "dev": true, - "peer": true, - "dependencies": { - "@noble/hashes": "1.2.0", - "@noble/secp256k1": "1.7.1", - "@scure/bip32": "1.1.5", - "@scure/bip39": "1.1.1" - } - }, - "node_modules/eth-gas-reporter/node_modules/ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "peer": true, - "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" - } - }, - "node_modules/ethereum-bloom-filters": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.1.0.tgz", - "integrity": "sha512-J1gDRkLpuGNvWYzWslBQR9cDV4nd4kfvVTE/Wy4Kkm4yb3EYRSlyi0eB/inTsSTTVyA0+HyzHgbr95Fn/Z1fSw==", - "dev": true, - "peer": true, - "dependencies": { - "@noble/hashes": "^1.4.0" - } - }, - "node_modules/ethereum-bloom-filters/node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/ethereumjs-abi": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", - "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", - "dependencies": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" - } - }, - "node_modules/ethereumjs-abi/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/ethereumjs-abi/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", -<<<<<<< HEAD -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/ethers": { - "version": "6.13.1", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.13.1.tgz", - "integrity": "sha512-hdJ2HOxg/xx97Lm9HdCWk949BfYqYWpyw4//78SiwOLgASyfrNszfMUNB2joKjvGUdwhHfaiMMFFwacVVoLR9A==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/ethers-io/" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@adraffy/ens-normalize": "1.10.1", - "@noble/curves": "1.2.0", - "@noble/hashes": "1.3.2", - "@types/node": "18.15.13", - "aes-js": "4.0.0-beta.5", - "tslib": "2.4.0", - "ws": "8.17.1" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/ethers/node_modules/@types/node": { - "version": "18.15.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", - "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==" - }, - "node_modules/ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", - "dev": true, - "peer": true, - "dependencies": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ethjs-unit/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true, - "peer": true - }, - "node_modules/ethjs-util": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "dependencies": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, -<<<<<<< HEAD - "node_modules/fast-base64-decode": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz", - "integrity": "sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==" - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", -<<<<<<< HEAD - "devOptional": true -======= - "dev": true, - "peer": true ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "peer": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "peer": true - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "peer": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-replace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", - "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", - "dev": true, - "peer": true, - "dependencies": { - "array-back": "^3.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "bin": { - "flat": "cli.js" - } - }, - "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, -<<<<<<< HEAD - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", -<<<<<<< HEAD -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fp-ts": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", - "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==" - }, - "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "peer": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true, - "peer": true - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", -<<<<<<< HEAD - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", -<<<<<<< HEAD -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, -<<<<<<< HEAD - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/ghost-testrpc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", - "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", - "dev": true, - "peer": true, - "dependencies": { - "chalk": "^2.4.2", - "node-emoji": "^1.10.0" - }, - "bin": { - "testrpc-sc": "index.js" - } - }, - "node_modules/ghost-testrpc/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "peer": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ghost-testrpc/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ghost-testrpc/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "peer": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/ghost-testrpc/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "peer": true - }, - "node_modules/ghost-testrpc/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/ghost-testrpc/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ghost-testrpc/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "peer": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, - "peer": true, - "dependencies": { - "global-prefix": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, - "peer": true, - "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "engines": { - "node": ">=6" - } - }, -<<<<<<< HEAD - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, - "peer": true, - "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", -<<<<<<< HEAD -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "dev": true, - "peer": true, - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, - "node_modules/handlebars/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/hardhat": { - "version": "2.22.6", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.22.6.tgz", - "integrity": "sha512-abFEnd9QACwEtSvZZGSmzvw7N3zhQN1cDKz5SLHAupfG24qTHofCjqvD5kT5Wwsq5XOL0ON1Mq5rr4v0XX5ciw==", - "dependencies": { - "@ethersproject/abi": "^5.1.2", - "@metamask/eth-sig-util": "^4.0.0", - "@nomicfoundation/edr": "^0.4.1", - "@nomicfoundation/ethereumjs-common": "4.0.4", - "@nomicfoundation/ethereumjs-tx": "5.0.4", - "@nomicfoundation/ethereumjs-util": "9.0.4", - "@nomicfoundation/solidity-analyzer": "^0.1.0", - "@sentry/node": "^5.18.1", - "@types/bn.js": "^5.1.0", - "@types/lru-cache": "^5.1.0", - "adm-zip": "^0.4.16", - "aggregate-error": "^3.0.0", - "ansi-escapes": "^4.3.0", - "boxen": "^5.1.2", - "chalk": "^2.4.2", - "chokidar": "^3.4.0", - "ci-info": "^2.0.0", - "debug": "^4.1.1", - "enquirer": "^2.3.0", - "env-paths": "^2.2.0", - "ethereum-cryptography": "^1.0.3", - "ethereumjs-abi": "^0.6.8", - "find-up": "^2.1.0", - "fp-ts": "1.19.3", - "fs-extra": "^7.0.1", - "glob": "7.2.0", - "immutable": "^4.0.0-rc.12", - "io-ts": "1.10.4", - "keccak": "^3.0.2", - "lodash": "^4.17.11", - "mnemonist": "^0.38.0", - "mocha": "^10.0.0", - "p-map": "^4.0.0", - "raw-body": "^2.4.1", - "resolve": "1.17.0", - "semver": "^6.3.0", - "solc": "0.8.26", - "source-map-support": "^0.5.13", - "stacktrace-parser": "^0.1.10", - "tsort": "0.0.1", - "undici": "^5.14.0", - "uuid": "^8.3.2", - "ws": "^7.4.6" - }, - "bin": { - "hardhat": "internal/cli/bootstrap.js" - }, - "peerDependencies": { - "ts-node": "*", - "typescript": "*" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, - "node_modules/hardhat-gas-reporter": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.10.tgz", - "integrity": "sha512-02N4+So/fZrzJ88ci54GqwVA3Zrf0C9duuTyGt0CFRIh/CdNwbnTgkXkRfojOMLBQ+6t+lBIkgbsOtqMvNwikA==", - "dev": true, - "peer": true, - "dependencies": { - "array-uniq": "1.0.3", - "eth-gas-reporter": "^0.2.25", - "sha1": "^1.1.1" - }, - "peerDependencies": { - "hardhat": "^2.0.2" - } - }, - "node_modules/hardhat/node_modules/@noble/hashes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", - "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, - "node_modules/hardhat/node_modules/@scure/bip32": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", - "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "@noble/hashes": "~1.2.0", - "@noble/secp256k1": "~1.7.0", - "@scure/base": "~1.1.0" - } - }, - "node_modules/hardhat/node_modules/@scure/bip39": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", - "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "@noble/hashes": "~1.2.0", - "@scure/base": "~1.1.0" - } - }, - "node_modules/hardhat/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/hardhat/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/hardhat/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/hardhat/node_modules/ethereum-cryptography": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", - "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", - "dependencies": { - "@noble/hashes": "1.2.0", - "@noble/secp256k1": "1.7.1", - "@scure/bip32": "1.1.5", - "@scure/bip39": "1.1.1" - } - }, - "node_modules/hardhat/node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/hardhat/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/hardhat/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/hardhat/node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, -<<<<<<< HEAD - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", -<<<<<<< HEAD -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", -<<<<<<< HEAD -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", -<<<<<<< HEAD - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dependencies": { - "has-symbols": "^1.0.3" - }, -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", -<<<<<<< HEAD -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "bin": { - "he": "bin/he" - } - }, - "node_modules/heap": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", - "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", - "dev": true, - "peer": true - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/http-basic": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", - "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", - "dev": true, - "peer": true, - "dependencies": { - "caseless": "^0.12.0", - "concat-stream": "^1.6.2", - "http-response-object": "^3.0.1", - "parse-cache-control": "^1.0.1" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-response-object": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", - "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", - "dev": true, - "peer": true, - "dependencies": { - "@types/node": "^10.0.3" - } - }, - "node_modules/http-response-object/node_modules/@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true, - "peer": true - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, -<<<<<<< HEAD - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/immer": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.2.tgz", - "integrity": "sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==", - "dev": true, - "peer": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/immer" - } - }, - "node_modules/immutable": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz", - "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==" - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "peer": true - }, -<<<<<<< HEAD - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/io-ts": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", - "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", - "dependencies": { - "fp-ts": "^1.0.0" - } - }, -<<<<<<< HEAD - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, -<<<<<<< HEAD - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dependencies": { - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, -<<<<<<< HEAD - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, -<<<<<<< HEAD - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "engines": { - "node": ">=8" - } - }, -<<<<<<< HEAD - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, -<<<<<<< HEAD - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" -======= - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, - "peer": true ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "peer": true - }, -<<<<<<< HEAD - "node_modules/isomorphic-unfetch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz", - "integrity": "sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==", - "dependencies": { - "node-fetch": "^2.6.1", - "unfetch": "^4.2.0" - } - }, - "node_modules/js-cookie": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", - "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==" - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", -<<<<<<< HEAD - "devOptional": true -======= - "dev": true, - "peer": true ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "peer": true - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "peer": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonschema": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", - "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", - "dev": true, - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/keccak": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", - "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", - "hasInstallScript": true, - "dependencies": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "peer": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "dev": true, - "peer": true - }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", -<<<<<<< HEAD - "devOptional": true, -======= - "dev": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "peer": true - }, - "node_modules/lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", -<<<<<<< HEAD - "devOptional": true -======= - "dev": true, - "peer": true ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "dev": true, - "peer": true, - "dependencies": { - "get-func-name": "^2.0.1" - } - }, - "node_modules/lru_map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==" - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "devOptional": true, - "peer": true - }, - "node_modules/markdown-table": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", - "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", - "dev": true, - "peer": true - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micro-ftch": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", - "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==", - "dev": true, - "peer": true - }, - "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", - "dev": true, - "peer": true, - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", -<<<<<<< HEAD -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", -<<<<<<< HEAD -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", -<<<<<<< HEAD -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "peer": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mnemonist": { - "version": "0.38.5", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", - "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", - "dependencies": { - "obliterator": "^2.0.0" - } - }, - "node_modules/mocha": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.6.0.tgz", - "integrity": "sha512-hxjt4+EEB0SA0ZDygSS015t65lJw/I2yRCS3Ae+SJ5FrbzrXgfYwJr96f0OvIXdj7h4lv/vLCrH3rkiuizFSvw==", - "dependencies": { - "ansi-colors": "^4.1.3", - "browser-stdout": "^1.3.1", - "chokidar": "^3.5.3", - "debug": "^4.3.5", - "diff": "^5.2.0", - "escape-string-regexp": "^4.0.0", - "find-up": "^5.0.0", - "glob": "^8.1.0", - "he": "^1.2.0", - "js-yaml": "^4.1.0", - "log-symbols": "^4.1.0", - "minimatch": "^5.1.6", - "ms": "^2.1.3", - "serialize-javascript": "^6.0.2", - "strip-json-comments": "^3.1.1", - "supports-color": "^8.1.1", - "workerpool": "^6.5.1", - "yargs": "^16.2.0", - "yargs-parser": "^20.2.9", - "yargs-unparser": "^2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/mocha/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mocha/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/mocha/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/ndjson": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ndjson/-/ndjson-2.0.0.tgz", - "integrity": "sha512-nGl7LRGrzugTtaFcJMhLbpzJM6XdivmbkdlaGcrk/LXg2KL/YBC6z1g70xh0/al+oFuVFP8N8kiWRucmeEH/qQ==", - "dev": true, - "peer": true, - "dependencies": { - "json-stringify-safe": "^5.0.1", - "minimist": "^1.2.5", - "readable-stream": "^3.6.0", - "split2": "^3.0.0", - "through2": "^4.0.0" - }, - "bin": { - "ndjson": "cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true, - "peer": true - }, - "node_modules/node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, - "node_modules/node-emoji": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", - "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", - "dev": true, - "peer": true, - "dependencies": { - "lodash": "^4.17.21" - } - }, -<<<<<<< HEAD - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/node-gyp-build": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", - "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/nofilter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", - "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", -<<<<<<< HEAD -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "engines": { - "node": ">=12.19" - } - }, - "node_modules/nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", - "dev": true, - "peer": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", - "dev": true, - "peer": true, - "dependencies": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/number-to-bn/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true, - "peer": true - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", -<<<<<<< HEAD - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obliterator": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", - "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==" - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "peer": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/ordinal": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ordinal/-/ordinal-1.0.3.tgz", - "integrity": "sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ==", - "dev": true, - "peer": true - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "engines": { - "node": ">=4" - } - }, - "node_modules/parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", - "dev": true, - "peer": true - }, - "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, -<<<<<<< HEAD - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "engines": { - "node": ">= 0.4" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "peer": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "peer": true - }, - "node_modules/promise": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", - "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", - "dev": true, - "peer": true, - "dependencies": { - "asap": "~2.0.6" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "peer": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, -<<<<<<< HEAD - "node_modules/proper-lockfile": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", - "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", - "dependencies": { - "graceful-fs": "^4.2.4", - "retry": "^0.12.0", - "signal-exit": "^3.0.2" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" -======= - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true, - "peer": true ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", -<<<<<<< HEAD - "devOptional": true, -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.12.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.2.tgz", - "integrity": "sha512-x+NLUpx9SYrcwXtX7ob1gnkSems4i/mGZX5SlYxwIau6RrUSODO89TR/XDGGpn5RPWSYIB+aSfuSlV5+CmbTBg==", - "dev": true, - "peer": true, - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "peer": true - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "peer": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/recursive-readdir": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", - "dev": true, - "peer": true, - "dependencies": { - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/reduce-flatten": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", - "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, -<<<<<<< HEAD - "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dependencies": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/req-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", - "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", - "dev": true, - "peer": true, - "dependencies": { - "req-from": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/req-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", - "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", - "dev": true, - "peer": true, - "dependencies": { - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", -<<<<<<< HEAD - "devOptional": true, -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dependencies": { - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, -<<<<<<< HEAD - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "engines": { - "node": ">= 4" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "peer": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "dependencies": { - "bn.js": "^5.2.0" - }, - "bin": { - "rlp": "bin/rlp" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "peer": true, - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, -<<<<<<< HEAD - "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-array-concat/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, -<<<<<<< HEAD - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sc-istanbul": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", - "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", - "dev": true, - "peer": true, - "dependencies": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "istanbul": "lib/cli.js" - } - }, - "node_modules/sc-istanbul/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "peer": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/sc-istanbul/node_modules/glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "peer": true, - "dependencies": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/sc-istanbul/node_modules/has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sc-istanbul/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "peer": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/sc-istanbul/node_modules/js-yaml/node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "peer": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/sc-istanbul/node_modules/resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", - "dev": true, - "peer": true - }, - "node_modules/sc-istanbul/node_modules/supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", - "dev": true, - "peer": true, - "dependencies": { - "has-flag": "^1.0.0" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" - }, - "node_modules/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", - "hasInstallScript": true, - "dependencies": { - "elliptic": "^6.5.4", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", -<<<<<<< HEAD -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, -<<<<<<< HEAD - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/sha1": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", - "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", - "dev": true, - "peer": true, - "dependencies": { - "charenc": ">= 0.0.1", - "crypt": ">= 0.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dev": true, - "peer": true, - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", -<<<<<<< HEAD -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -<<<<<<< HEAD - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true, - "peer": true - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", -<<<<<<< HEAD - "devOptional": true, -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/solc": { - "version": "0.8.26", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.8.26.tgz", - "integrity": "sha512-yiPQNVf5rBFHwN6SIf3TUUvVAFKcQqmSUFeq+fb6pNRCo0ZCgpYOZDi3BVoezCPIAcKrVYd/qXlBLUP9wVrZ9g==", - "dependencies": { - "command-exists": "^1.2.8", - "commander": "^8.1.0", - "follow-redirects": "^1.12.1", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "bin": { - "solcjs": "solc.js" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/solc/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "bin": { - "semver": "bin/semver" - } - }, -<<<<<<< HEAD - "node_modules/solidity-ast": { - "version": "0.4.56", - "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.56.tgz", - "integrity": "sha512-HgmsA/Gfklm/M8GFbCX/J1qkVH0spXHgALCNZ8fA8x5X+MFdn/8CP2gr5OVyXjXw6RZTPC/Sxl2RUDQOXyNMeA==", - "dependencies": { - "array.prototype.findlast": "^1.2.2" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/solidity-coverage": { - "version": "0.8.12", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.12.tgz", - "integrity": "sha512-8cOB1PtjnjFRqOgwFiD8DaUsYJtVJ6+YdXQtSZDrLGf8cdhhh8xzTtGzVTGeBf15kTv0v7lYPJlV/az7zLEPJw==", - "dev": true, - "peer": true, - "dependencies": { - "@ethersproject/abi": "^5.0.9", - "@solidity-parser/parser": "^0.18.0", - "chalk": "^2.4.2", - "death": "^1.1.0", - "difflib": "^0.2.4", - "fs-extra": "^8.1.0", - "ghost-testrpc": "^0.0.2", - "global-modules": "^2.0.0", - "globby": "^10.0.1", - "jsonschema": "^1.2.4", - "lodash": "^4.17.21", - "mocha": "^10.2.0", - "node-emoji": "^1.10.0", - "pify": "^4.0.1", - "recursive-readdir": "^2.2.2", - "sc-istanbul": "^0.4.5", - "semver": "^7.3.4", - "shelljs": "^0.8.3", - "web3-utils": "^1.3.6" - }, - "bin": { - "solidity-coverage": "plugins/bin.js" - }, - "peerDependencies": { - "hardhat": "^2.11.0" - } - }, - "node_modules/solidity-coverage/node_modules/@solidity-parser/parser": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.18.0.tgz", - "integrity": "sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA==", - "dev": true, - "peer": true - }, - "node_modules/solidity-coverage/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "peer": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "peer": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/solidity-coverage/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "peer": true - }, - "node_modules/solidity-coverage/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/solidity-coverage/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "peer": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/solidity-coverage/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "peer": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/solidity-coverage/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, - "peer": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/solidity-coverage/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "peer": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "amdefine": ">=0.0.4" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", - "dev": true, - "peer": true, - "dependencies": { - "readable-stream": "^3.0.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, - "peer": true - }, - "node_modules/stacktrace-parser": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", - "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", - "dependencies": { - "type-fest": "^0.7.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/stacktrace-parser/node_modules/type-fest": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", - "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/stl-contracts": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/stl-contracts/-/stl-contracts-2.5.1.tgz", - "integrity": "sha512-fkIq5BPq2/MTkQEDgXRM5WtrpQXqar3lDtha7N446UoCvNWP2isKfcRJ0RKatyMegGvRK1yWugDbbR3OGZiGXg==" - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-format": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string-format/-/string-format-2.0.0.tgz", - "integrity": "sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==", - "dev": true, - "peer": true - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, -<<<<<<< HEAD - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", - "dependencies": { - "is-hex-prefixed": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/sync-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", - "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", - "dev": true, - "peer": true, - "dependencies": { - "http-response-object": "^3.0.1", - "sync-rpc": "^1.2.1", - "then-request": "^6.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/sync-rpc": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", - "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", - "dev": true, - "peer": true, - "dependencies": { - "get-port": "^3.1.0" - } - }, - "node_modules/table": { - "version": "6.8.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", - "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", -<<<<<<< HEAD - "devOptional": true, -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table-layout": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", - "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", - "dev": true, - "peer": true, - "dependencies": { - "array-back": "^4.0.1", - "deep-extend": "~0.6.0", - "typical": "^5.2.0", - "wordwrapjs": "^4.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/table-layout/node_modules/array-back": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", - "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/table-layout/node_modules/typical": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", - "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/then-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", - "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", - "dev": true, - "peer": true, - "dependencies": { - "@types/concat-stream": "^1.6.0", - "@types/form-data": "0.0.33", - "@types/node": "^8.0.0", - "@types/qs": "^6.2.31", - "caseless": "~0.12.0", - "concat-stream": "^1.6.0", - "form-data": "^2.2.0", - "http-basic": "^8.1.1", - "http-response-object": "^3.0.1", - "promise": "^8.0.0", - "qs": "^6.4.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/then-request/node_modules/@types/node": { - "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", - "dev": true, - "peer": true - }, - "node_modules/then-request/node_modules/form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "dev": true, - "peer": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "peer": true, - "dependencies": { - "readable-stream": "3" - } - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, -<<<<<<< HEAD - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/ts-command-line-args": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz", - "integrity": "sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==", - "dev": true, - "peer": true, - "dependencies": { - "chalk": "^4.1.0", - "command-line-args": "^5.1.1", - "command-line-usage": "^6.1.0", - "string-format": "^2.0.0" - }, - "bin": { - "write-markdown": "dist/write-markdown.js" - } - }, - "node_modules/ts-essentials": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", - "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", - "dev": true, - "peer": true, - "peerDependencies": { - "typescript": ">=3.7.0" - } - }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "devOptional": true, - "peer": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "devOptional": true, - "peer": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" - }, - "node_modules/tsort": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", - "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==" - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "node_modules/tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" - }, - "node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "peer": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typechain": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.3.2.tgz", - "integrity": "sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==", - "dev": true, - "peer": true, - "dependencies": { - "@types/prettier": "^2.1.1", - "debug": "^4.3.1", - "fs-extra": "^7.0.0", - "glob": "7.1.7", - "js-sha3": "^0.8.0", - "lodash": "^4.17.15", - "mkdirp": "^1.0.4", - "prettier": "^2.3.1", - "ts-command-line-args": "^2.2.0", - "ts-essentials": "^7.0.1" - }, - "bin": { - "typechain": "dist/cli/cli.js" - }, - "peerDependencies": { - "typescript": ">=4.3.0" - } - }, - "node_modules/typechain/node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "peer": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/typechain/node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/typechain/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "peer": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/typechain/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "peer": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/typechain/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 4.0.0" - } - }, -<<<<<<< HEAD - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true, - "peer": true - }, - "node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", - "devOptional": true, - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typical": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", - "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/uglify-js": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz", - "integrity": "sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==", - "dev": true, - "optional": true, - "peer": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, -<<<<<<< HEAD - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/undici": { - "version": "5.28.4", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", - "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", - "dependencies": { - "@fastify/busboy": "^2.0.0" - }, - "engines": { - "node": ">=14.0" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, -<<<<<<< HEAD - "node_modules/unfetch": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", - "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==" - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", -<<<<<<< HEAD - "devOptional": true, -======= - "dev": true, - "peer": true, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", - "dev": true, - "peer": true - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "devOptional": true, - "peer": true - }, - "node_modules/web3-utils": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.4.tgz", - "integrity": "sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==", - "dev": true, - "peer": true, - "dependencies": { - "@ethereumjs/util": "^8.1.0", - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereum-cryptography": "^2.1.2", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-utils/node_modules/@noble/curves": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", - "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", - "dev": true, - "peer": true, - "dependencies": { - "@noble/hashes": "1.4.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/web3-utils/node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/web3-utils/node_modules/ethereum-cryptography": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", - "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", - "dev": true, - "peer": true, - "dependencies": { - "@noble/curves": "1.4.2", - "@noble/hashes": "1.4.0", - "@scure/bip32": "1.4.0", - "@scure/bip39": "1.3.0" - } - }, -<<<<<<< HEAD - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "peer": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, -<<<<<<< HEAD - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "node_modules/widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dependencies": { - "string-width": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true, - "peer": true - }, - "node_modules/wordwrapjs": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", - "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", - "dev": true, - "peer": true, - "dependencies": { - "reduce-flatten": "^2.0.0", - "typical": "^5.2.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/wordwrapjs/node_modules/typical": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", - "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/workerpool": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", - "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==" - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true + "name": "hardhat", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "hardhat", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@nomicfoundation/hardhat-ethers": "^3.0.6", + "@openzeppelin/contracts": "^5.0.2", + "@openzeppelin/contracts-upgradeable": "^5.0.2", + "@openzeppelin/hardhat-upgrades": "^3.2.1", + "@openzeppelin/upgrades-core": "^1.35.0", + "dotenv": "^16.4.5", + "ethers": "^6.13.1", + "hardhat": "^2.22.6", + "stl-contracts": "^2.5.1" + }, + "devDependencies": { + "@nomicfoundation/hardhat-ignition-ethers": "^0.15.5", + "@nomicfoundation/hardhat-toolbox": "^5.0.0", + "@nomiclabs/hardhat-etherscan": "^3.1.8" + } + }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", + "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==" + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-1.2.2.tgz", + "integrity": "sha512-Nr1QJIbW/afYYGzYvrF70LtaHrIRtd4TNAglX8BvlfxJLZ45SAmueIKYl5tWoNBPzp65ymXGFK0Bb1vZUpuc9g==", + "dependencies": { + "@aws-crypto/util": "^1.2.2", + "@aws-sdk/types": "^3.1.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha256-js/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/util": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-1.2.2.tgz", + "integrity": "sha512-H8PjG5WJ4wz0UXAFXeJjWCW1vkvIJ3qUUD+rGRwJ2/hj+xT58Qle2MTql/2MGzkU+1JLAFuR6aJpLAjHwhmwwg==", + "dependencies": { + "@aws-sdk/types": "^3.1.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/util/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-sdk/types": { + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.609.0.tgz", + "integrity": "sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q==", + "dependencies": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/types/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, + "node_modules/@aws-sdk/util-utf8-browser": { + "version": "3.259.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", + "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", + "dependencies": { + "tslib": "^2.3.1" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "devOptional": true, + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "dev": true, + "peer": true, + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethereumjs/util": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", + "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", + "dev": true, + "peer": true, + "dependencies": { + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethereumjs/util/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/@ethersproject/abi": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", + "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", + "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/address": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/rlp": "^5.7.0" + } + }, + "node_modules/@ethersproject/base64": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", + "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0" + } + }, + "node_modules/@ethersproject/basex": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", + "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", + "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0" + } + }, + "node_modules/@ethersproject/contracts": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", + "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/hdnode": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", + "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/json-wallets": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", + "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", + "dev": true, + "peer": true + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", + "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", + "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ] + }, + "node_modules/@ethersproject/networks": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/pbkdf2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", + "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/sha2": "^5.7.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", + "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/providers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "node_modules/@ethersproject/providers/node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@ethersproject/random": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", + "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", + "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/sha2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", + "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", + "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/solidity": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", + "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", + "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" + } + }, + "node_modules/@ethersproject/units": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", + "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/wallet": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", + "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/json-wallets": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", + "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/wordlists": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", + "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "devOptional": true, + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "devOptional": true, + "peer": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "devOptional": true, + "peer": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@metamask/eth-sig-util": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", + "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", + "dependencies": { + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^6.2.1", + "ethjs-util": "^0.1.6", + "tweetnacl": "^1.0.3", + "tweetnacl-util": "^0.15.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@metamask/eth-sig-util/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@metamask/eth-sig-util/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/@metamask/eth-sig-util/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/secp256k1": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", + "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "peer": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "peer": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nomicfoundation/edr": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.4.1.tgz", + "integrity": "sha512-NgrMo2rI9r28uidumvd+K2/AJLdxtXsUlJr3hj/pM6S1FCd/HiWaLeLa/cjCVPcE2u1rYAa3W6UFxLCB7S5Dhw==", + "dependencies": { + "@nomicfoundation/edr-darwin-arm64": "0.4.1", + "@nomicfoundation/edr-darwin-x64": "0.4.1", + "@nomicfoundation/edr-linux-arm64-gnu": "0.4.1", + "@nomicfoundation/edr-linux-arm64-musl": "0.4.1", + "@nomicfoundation/edr-linux-x64-gnu": "0.4.1", + "@nomicfoundation/edr-linux-x64-musl": "0.4.1", + "@nomicfoundation/edr-win32-x64-msvc": "0.4.1" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-darwin-arm64": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.4.1.tgz", + "integrity": "sha512-XuiUUnWAVNw7JYv7nRqDWfpBm21HOxCRBQ8lQnRnmiets9Ss2X5Ul9mvBheIPh/D0wBzwJ8TRtsSrorpwE79cA==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-darwin-x64": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.4.1.tgz", + "integrity": "sha512-N1MfJqEX5ixaXlyyrHnaYxzwIT27Nc/jUgLI7ts4/9kRvPTvyZRYmXS1ciKhmUFr/WvFckTCix2RJbZoGGtX7g==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-arm64-gnu": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.4.1.tgz", + "integrity": "sha512-bSPOfmcFjJwDgWOV5kgZHeqg2OWu1cINrHSGjig0aVHehjcoX4Sgayrj6fyAxcOV5NQKA6WcyTFll6NrCxzWRA==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-arm64-musl": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.4.1.tgz", + "integrity": "sha512-F/+DgOdeBFQDrk+SX4aFffJFBgJfd75ZtE2mjcWNAh/qWiS7NfUxdQX/5OvNo/H6EY4a+3bZH6Bgzqg4mEWvMw==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-x64-gnu": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.4.1.tgz", + "integrity": "sha512-POHhTWczIXCPhzKtY0Vt/l+VCqqCx5gNR5ErwSrNnLz/arfQobZFAU+nc61BX3Jch82TW8b3AbfGI73Kh7gO0w==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-x64-musl": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.4.1.tgz", + "integrity": "sha512-uu8oNp4Ozg3H1x1We0FF+rwXfFiAvsOm5GQ+OBx9YYOXnfDPWqguQfGIkhrti9GD0iYhfQ/WOG5wvp0IzzgGSg==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-win32-x64-msvc": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.4.1.tgz", + "integrity": "sha512-PaZHFw455z89ZiKYNTnKu+/TiVZVRI+mRJsbRTe2N0VlYfUBS1o2gdXBM12oP1t198HR7xQwEPPAslTFxGBqHA==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/ethereumjs-common": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz", + "integrity": "sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==", + "dependencies": { + "@nomicfoundation/ethereumjs-util": "9.0.4" + } + }, + "node_modules/@nomicfoundation/ethereumjs-rlp": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz", + "integrity": "sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==", + "bin": { + "rlp": "bin/rlp.cjs" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@nomicfoundation/ethereumjs-tx": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz", + "integrity": "sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==", + "dependencies": { + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "c-kzg": "^2.1.2" + }, + "peerDependenciesMeta": { + "c-kzg": { + "optional": true + } + } + }, + "node_modules/@nomicfoundation/ethereumjs-util": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz", + "integrity": "sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==", + "dependencies": { + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "c-kzg": "^2.1.2" + }, + "peerDependenciesMeta": { + "c-kzg": { + "optional": true + } + } + }, + "node_modules/@nomicfoundation/hardhat-chai-matchers": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.7.tgz", + "integrity": "sha512-RQfsiTwdf0SP+DtuNYvm4921X6VirCQq0Xyh+mnuGlTwEFSPZ/o27oQC+l+3Y/l48DDU7+ZcYBR+Fp+Rp94LfQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/chai-as-promised": "^7.1.3", + "chai-as-promised": "^7.1.1", + "deep-eql": "^4.0.1", + "ordinal": "^1.0.3" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-ethers": "^3.0.0", + "chai": "^4.2.0", + "ethers": "^6.1.0", + "hardhat": "^2.9.4" + } + }, + "node_modules/@nomicfoundation/hardhat-ethers": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.6.tgz", + "integrity": "sha512-/xzkFQAaHQhmIAYOQmvHBPwL+NkwLzT9gRZBsgWUYeV+E6pzXsBQsHfRYbAZ3XEYare+T7S+5Tg/1KDJgepSkA==", + "dependencies": { + "debug": "^4.1.1", + "lodash.isequal": "^4.5.0" + }, + "peerDependencies": { + "ethers": "^6.1.0", + "hardhat": "^2.0.0" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition/-/hardhat-ignition-0.15.5.tgz", + "integrity": "sha512-Y5nhFXFqt4owA6Ooag8ZBFDF2RAZElMXViknVIsi3m45pbQimS50ti6FU8HxfRkDnBARa40CIn7UGV0hrelzDw==", + "dev": true, + "peer": true, + "dependencies": { + "@nomicfoundation/ignition-core": "^0.15.5", + "@nomicfoundation/ignition-ui": "^0.15.5", + "chalk": "^4.0.0", + "debug": "^4.3.2", + "fs-extra": "^10.0.0", + "prompts": "^2.4.2" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-verify": "^2.0.1", + "hardhat": "^2.18.0" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition-ethers": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition-ethers/-/hardhat-ignition-ethers-0.15.5.tgz", + "integrity": "sha512-W6s1QN9CFxzSVZS6w9Jcj3WLaK32z2FP5MxNU2OKY1Fn9ZzLr+miXbUbWYuRHl6dxrrl6sE8cv33Cybv19pmCg==", + "dev": true, + "peerDependencies": { + "@nomicfoundation/hardhat-ethers": "^3.0.4", + "@nomicfoundation/hardhat-ignition": "^0.15.5", + "@nomicfoundation/ignition-core": "^0.15.5", + "ethers": "^6.7.0", + "hardhat": "^2.18.0" + } + }, + "node_modules/@nomicfoundation/hardhat-network-helpers": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.11.tgz", + "integrity": "sha512-uGPL7QSKvxrHRU69dx8jzoBvuztlLCtyFsbgfXIwIjnO3dqZRz2GNMHJoO3C3dIiUNM6jdNF4AUnoQKDscdYrA==", + "dev": true, + "peer": true, + "dependencies": { + "ethereumjs-util": "^7.1.4" + }, + "peerDependencies": { + "hardhat": "^2.9.5" + } + }, + "node_modules/@nomicfoundation/hardhat-toolbox": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-5.0.0.tgz", + "integrity": "sha512-FnUtUC5PsakCbwiVNsqlXVIWG5JIb5CEZoSXbJUsEBun22Bivx2jhF1/q9iQbzuaGpJKFQyOhemPB2+XlEE6pQ==", + "dev": true, + "peerDependencies": { + "@nomicfoundation/hardhat-chai-matchers": "^2.0.0", + "@nomicfoundation/hardhat-ethers": "^3.0.0", + "@nomicfoundation/hardhat-ignition-ethers": "^0.15.0", + "@nomicfoundation/hardhat-network-helpers": "^1.0.0", + "@nomicfoundation/hardhat-verify": "^2.0.0", + "@typechain/ethers-v6": "^0.5.0", + "@typechain/hardhat": "^9.0.0", + "@types/chai": "^4.2.0", + "@types/mocha": ">=9.1.0", + "@types/node": ">=18.0.0", + "chai": "^4.2.0", + "ethers": "^6.4.0", + "hardhat": "^2.11.0", + "hardhat-gas-reporter": "^1.0.8", + "solidity-coverage": "^0.8.1", + "ts-node": ">=8.0.0", + "typechain": "^8.3.0", + "typescript": ">=4.5.0" + } + }, + "node_modules/@nomicfoundation/hardhat-verify": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.8.tgz", + "integrity": "sha512-x/OYya7A2Kcz+3W/J78dyDHxr0ezU23DKTrRKfy5wDPCnePqnr79vm8EXqX3gYps6IjPBYyGPZ9K6E5BnrWx5Q==", + "devOptional": true, + "peer": true, + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@ethersproject/address": "^5.0.2", + "cbor": "^8.1.0", + "chalk": "^2.4.2", + "debug": "^4.1.1", + "lodash.clonedeep": "^4.5.0", + "semver": "^6.3.0", + "table": "^6.8.0", + "undici": "^5.14.0" + }, + "peerDependencies": { + "hardhat": "^2.0.4" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "devOptional": true, + "peer": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "devOptional": true, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "devOptional": true, + "peer": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "devOptional": true, + "peer": true + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "devOptional": true, + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "devOptional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "devOptional": true, + "peer": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomicfoundation/ignition-core": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-core/-/ignition-core-0.15.5.tgz", + "integrity": "sha512-FgvuoIXhakRSP524JzNQ4BviyzBBKpsFaOWubPZ4XACLT4/7vGqlJ/7DIn0D2NL2anQ2qs98/BNBY9WccXUX1Q==", + "dev": true, + "peer": true, + "dependencies": { + "@ethersproject/address": "5.6.1", + "@nomicfoundation/solidity-analyzer": "^0.1.1", + "cbor": "^9.0.0", + "debug": "^4.3.2", + "ethers": "^6.7.0", + "fs-extra": "^10.0.0", + "immer": "10.0.2", + "lodash": "4.17.21", + "ndjson": "2.0.0" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/@ethersproject/address": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.1.tgz", + "integrity": "sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/rlp": "^5.6.1" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/cbor": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-9.0.2.tgz", + "integrity": "sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==", + "dev": true, + "peer": true, + "dependencies": { + "nofilter": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@nomicfoundation/ignition-ui": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-ui/-/ignition-ui-0.15.5.tgz", + "integrity": "sha512-ZcE4rIn10qKahR4OqS8rl8NM2Fbg2QYiBXgMgj74ZI0++LlCcZgB5HyaBbX+lsnKHjTXtjYD3b+2mtg7jFbAMQ==", + "dev": true, + "peer": true + }, + "node_modules/@nomicfoundation/slang": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang/-/slang-0.15.1.tgz", + "integrity": "sha512-th7nxRWRXf583uHpWUCd8U7BYxIqJX2f3oZLff/mlPkqIr45pD2hLT/o00eCjrBIR8N7vybUULZg1CeThGNk7g==", + "dependencies": { + "@nomicfoundation/slang-darwin-arm64": "0.15.1", + "@nomicfoundation/slang-darwin-x64": "0.15.1", + "@nomicfoundation/slang-linux-arm64-gnu": "0.15.1", + "@nomicfoundation/slang-linux-arm64-musl": "0.15.1", + "@nomicfoundation/slang-linux-x64-gnu": "0.15.1", + "@nomicfoundation/slang-linux-x64-musl": "0.15.1", + "@nomicfoundation/slang-win32-arm64-msvc": "0.15.1", + "@nomicfoundation/slang-win32-ia32-msvc": "0.15.1", + "@nomicfoundation/slang-win32-x64-msvc": "0.15.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/slang-darwin-arm64": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-darwin-arm64/-/slang-darwin-arm64-0.15.1.tgz", + "integrity": "sha512-taPHlCUNNztQZJze9OlZFK9cZH8Ut4Ih4QJQo5CKebXx9vWOUtmSBfKv/M2P8hiV/iL7Q5sPwR7HY9uZYnb49Q==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/slang-darwin-x64": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-darwin-x64/-/slang-darwin-x64-0.15.1.tgz", + "integrity": "sha512-kgZh5KQe/UcbFqn1EpyrvBuT8E6I1kWSgGPtO25t90zAqFv23sMUPdn7wLpMjngkD+quIIgrzQGUtupS5YYEig==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/slang-linux-arm64-gnu": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-linux-arm64-gnu/-/slang-linux-arm64-gnu-0.15.1.tgz", + "integrity": "sha512-Iw8mepaccKRWllPU9l+hoe88LN9fScC0Px3nFeNQy26qk1ueO0tjovP1dhTvmGwHUxacOYPqhQTUn7Iu0oxNoQ==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/slang-linux-arm64-musl": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-linux-arm64-musl/-/slang-linux-arm64-musl-0.15.1.tgz", + "integrity": "sha512-zcesdQZwRgrT7ND+3TZUjRK/uGF20EfhEfCg8ZMhrb4Q7XaK1JvtHazIs03TV8Jcs30TPkEXks8Qi0Zdfy4RuA==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/slang-linux-x64-gnu": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-linux-x64-gnu/-/slang-linux-x64-gnu-0.15.1.tgz", + "integrity": "sha512-FSmAnzKm58TFIwx4r/wOZtqfDx0nI6AfvnOh8kLDF5OxpWW3r0q9fq8lyaUReg9C/ZgCZRBn+m5WGrNKCZcvPQ==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/slang-linux-x64-musl": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-linux-x64-musl/-/slang-linux-x64-musl-0.15.1.tgz", + "integrity": "sha512-hnoA/dgeHQ8aS0SReABYkxf0d/Q6DdaKsaYv6ev21wyQA7TROxT1X3nekECLGu1GYLML8pzvD9vyAMBRKOkkyg==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/slang-win32-arm64-msvc": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-win32-arm64-msvc/-/slang-win32-arm64-msvc-0.15.1.tgz", + "integrity": "sha512-2H0chHQ4uTh4l4UxN5fIVHR5mKaL5mfYTID6kxxxv2+KAh68EpYWwxLlkS5So90R2WcuPvFvTVKLm/uRo4h4dg==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/slang-win32-ia32-msvc": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-win32-ia32-msvc/-/slang-win32-ia32-msvc-0.15.1.tgz", + "integrity": "sha512-CVZWBnbpFlVBg/m7bsiw70jY3p9TGH9vxq0vLEEJ56yK+QPosxPrKMcADojtGjIOjWjPSZ+lCoo5ilnW0a249g==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/slang-win32-x64-msvc": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-win32-x64-msvc/-/slang-win32-x64-msvc-0.15.1.tgz", + "integrity": "sha512-cyER8M1fdBTzIfihy55d4LGGlN/eQxDqfRUTXgJf1VvNR98tRB0Q3nBfyh5PK2yP98B4lMt3RJYDqTQu+dOVDA==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.2.tgz", + "integrity": "sha512-q4n32/FNKIhQ3zQGGw5CvPF6GTvDCpYwIf7bEY/dZTZbgfDsHyjJwURxUJf3VQuuJj+fDIFl4+KkBVbw4Ef6jA==", + "engines": { + "node": ">= 12" + }, + "optionalDependencies": { + "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.2", + "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.2", + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.2" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.2.tgz", + "integrity": "sha512-JaqcWPDZENCvm++lFFGjrDd8mxtf+CtLd2MiXvMNTBD33dContTZ9TWETwNFwg7JTJT5Q9HEecH7FA+HTSsIUw==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-darwin-x64": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.2.tgz", + "integrity": "sha512-fZNmVztrSXC03e9RONBT+CiksSeYcxI1wlzqyr0L7hsQlK1fzV+f04g2JtQ1c/Fe74ZwdV6aQBdd6Uwl1052sw==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.2.tgz", + "integrity": "sha512-3d54oc+9ZVBuB6nbp8wHylk4xh0N0Gc+bk+/uJae+rUgbOBwQSfuGIbAZt1wBXs5REkSmynEGcqx6DutoK0tPA==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.2.tgz", + "integrity": "sha512-iDJfR2qf55vgsg7BtJa7iPiFAsYf2d0Tv/0B+vhtnI16+wfQeTbP7teookbGvAo0eJo7aLLm0xfS/GTkvHIucA==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.2.tgz", + "integrity": "sha512-9dlHMAt5/2cpWyuJ9fQNOUXFB/vgSFORg1jpjX1Mh9hJ/MfZXlDdHQ+DpFCs32Zk5pxRBb07yGvSHk9/fezL+g==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.2.tgz", + "integrity": "sha512-GzzVeeJob3lfrSlDKQw2bRJ8rBf6mEYaWY+gW0JnTDHINA0s2gPR4km5RLIj1xeZZOYz4zRw+AEeYgLRqB2NXg==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.2.tgz", + "integrity": "sha512-Fdjli4DCcFHb4Zgsz0uEJXZ2K7VEO+w5KVv7HmT7WO10iODdU9csC2az4jrhEsRtiR9Gfd74FlG0NYlw1BMdyA==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomiclabs/hardhat-etherscan": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.8.tgz", + "integrity": "sha512-v5F6IzQhrsjHh6kQz4uNrym49brK9K5bYCq2zQZ729RYRaifI9hHbtmK+KkIVevfhut7huQFEQ77JLRMAzWYjQ==", + "deprecated": "The @nomiclabs/hardhat-etherscan package is deprecated, please use @nomicfoundation/hardhat-verify instead", + "dev": true, + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@ethersproject/address": "^5.0.2", + "cbor": "^8.1.0", + "chalk": "^2.4.2", + "debug": "^4.1.1", + "fs-extra": "^7.0.1", + "lodash": "^4.17.11", + "semver": "^6.3.0", + "table": "^6.8.0", + "undici": "^5.14.0" + }, + "peerDependencies": { + "hardhat": "^2.0.4" + } + }, + "node_modules/@nomiclabs/hardhat-etherscan/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomiclabs/hardhat-etherscan/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomiclabs/hardhat-etherscan/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@nomiclabs/hardhat-etherscan/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@nomiclabs/hardhat-etherscan/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@nomiclabs/hardhat-etherscan/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@nomiclabs/hardhat-etherscan/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomiclabs/hardhat-etherscan/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@nomiclabs/hardhat-etherscan/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomiclabs/hardhat-etherscan/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/@openzeppelin/contracts": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.0.2.tgz", + "integrity": "sha512-ytPc6eLGcHHnapAZ9S+5qsdomhjo6QBHTDRRBFfTxXIpsicMhVPouPgmUPebZZZGX7vt9USA+Z+0M0dSVtSUEA==" + }, + "node_modules/@openzeppelin/contracts-upgradeable": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.0.2.tgz", + "integrity": "sha512-0MmkHSHiW2NRFiT9/r5Lu4eJq5UJ4/tzlOgYXNAIj/ONkQTVnz22pLxDvp4C4uZ9he7ZFvGn3Driptn1/iU7tQ==", + "peerDependencies": { + "@openzeppelin/contracts": "5.0.2" + } + }, + "node_modules/@openzeppelin/defender-sdk-base-client": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-base-client/-/defender-sdk-base-client-1.14.3.tgz", + "integrity": "sha512-4yG9E8N1c/ZP2jNR+Ah19wi7SBKpauAV/VcYcm7rg1dltDbzbH/oZnnXJlymT7IfjTPXkKHW8TPsaqz3EjS7tA==", + "dependencies": { + "amazon-cognito-identity-js": "^6.3.6", + "async-retry": "^1.3.3" + } + }, + "node_modules/@openzeppelin/defender-sdk-deploy-client": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-deploy-client/-/defender-sdk-deploy-client-1.14.3.tgz", + "integrity": "sha512-51WIZJz251lndK7uQU4gBE0gBX+2ZNTgf+hemtJUEPCpHtkooBRFFMID3EPGMKXVqf872pU8K3Huu9PyYQu6bw==", + "dependencies": { + "@openzeppelin/defender-sdk-base-client": "1.14.3", + "axios": "^1.7.2", + "lodash": "^4.17.21" + } + }, + "node_modules/@openzeppelin/defender-sdk-network-client": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-network-client/-/defender-sdk-network-client-1.14.3.tgz", + "integrity": "sha512-qrJLs2ubKSwrhP0x4V2QOPhlc1q8TYnkAcvjvk34VXMS8lhY1cpXSGoxnTw3Mi+eCSE1xOzKWISLi1UAOQOJIw==", + "dependencies": { + "@openzeppelin/defender-sdk-base-client": "1.14.3", + "axios": "^1.7.2", + "lodash": "^4.17.21" + } + }, + "node_modules/@openzeppelin/hardhat-upgrades": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-3.2.1.tgz", + "integrity": "sha512-Zy5M3QhkzwGdpzQmk+xbWdYOGJWjoTvwbBKYLhctu9B91DoprlhDRaZUwCtunwTdynkTDGdVfGr0kIkvycyKjw==", + "dependencies": { + "@openzeppelin/defender-sdk-base-client": "^1.10.0", + "@openzeppelin/defender-sdk-deploy-client": "^1.10.0", + "@openzeppelin/defender-sdk-network-client": "^1.10.0", + "@openzeppelin/upgrades-core": "^1.35.0", + "chalk": "^4.1.0", + "debug": "^4.1.1", + "ethereumjs-util": "^7.1.5", + "proper-lockfile": "^4.1.1", + "undici": "^6.11.1" + }, + "bin": { + "migrate-oz-cli-project": "dist/scripts/migrate-oz-cli-project.js" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-ethers": "^3.0.0", + "@nomicfoundation/hardhat-verify": "^2.0.0", + "ethers": "^6.6.0", + "hardhat": "^2.0.2" + }, + "peerDependenciesMeta": { + "@nomicfoundation/hardhat-verify": { + "optional": true + } + } + }, + "node_modules/@openzeppelin/hardhat-upgrades/node_modules/undici": { + "version": "6.19.5", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.5.tgz", + "integrity": "sha512-LryC15SWzqQsREHIOUybavaIHF5IoL0dJ9aWWxL/PgT1KfqAW5225FZpDUFlt9xiDMS2/S7DOKhFWA7RLksWdg==", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/@openzeppelin/upgrades-core": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.35.0.tgz", + "integrity": "sha512-XwwhJyPxACQ7rMhKAPCL6rhTXhbeumeQ3opmurEsHg025vHnISHwTPHd5VxzmOwbMBIJ7em1lnRTu+J2/IUWFQ==", + "dependencies": { + "@nomicfoundation/slang": "^0.15.1", + "cbor": "^9.0.0", + "chalk": "^4.1.0", + "compare-versions": "^6.0.0", + "debug": "^4.1.1", + "ethereumjs-util": "^7.0.3", + "minimist": "^1.2.7", + "proper-lockfile": "^4.1.1", + "solidity-ast": "^0.4.51" + }, + "bin": { + "openzeppelin-upgrades-core": "dist/cli/cli.js" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/cbor": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-9.0.2.tgz", + "integrity": "sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==", + "dependencies": { + "nofilter": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@scure/base": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.7.tgz", + "integrity": "sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g==", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@sentry/core": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", + "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/core/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@sentry/hub": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", + "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", + "dependencies": { + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/hub/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@sentry/minimal": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", + "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/minimal/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@sentry/node": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", + "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", + "dependencies": { + "@sentry/core": "5.30.0", + "@sentry/hub": "5.30.0", + "@sentry/tracing": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "cookie": "^0.4.1", + "https-proxy-agent": "^5.0.0", + "lru_map": "^0.3.3", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/node/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@sentry/tracing": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", + "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/tracing/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@sentry/types": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", + "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", + "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", + "dependencies": { + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/types/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, + "node_modules/@solidity-parser/parser": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.5.tgz", + "integrity": "sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==", + "dev": true, + "peer": true, + "dependencies": { + "antlr4ts": "^0.5.0-alpha.4" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "devOptional": true, + "peer": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "devOptional": true, + "peer": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "devOptional": true, + "peer": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "devOptional": true, + "peer": true + }, + "node_modules/@typechain/ethers-v6": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@typechain/ethers-v6/-/ethers-v6-0.5.1.tgz", + "integrity": "sha512-F+GklO8jBWlsaVV+9oHaPh5NJdd6rAKN4tklGfInX1Q7h0xPgVLP39Jl3eCulPB5qexI71ZFHwbljx4ZXNfouA==", + "dev": true, + "peer": true, + "dependencies": { + "lodash": "^4.17.15", + "ts-essentials": "^7.0.1" + }, + "peerDependencies": { + "ethers": "6.x", + "typechain": "^8.3.2", + "typescript": ">=4.7.0" + } + }, + "node_modules/@typechain/hardhat": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-9.1.0.tgz", + "integrity": "sha512-mtaUlzLlkqTlfPwB3FORdejqBskSnh+Jl8AIJGjXNAQfRQ4ofHADPl1+oU7Z3pAJzmZbUXII8MhOLQltcHgKnA==", + "dev": true, + "peer": true, + "dependencies": { + "fs-extra": "^9.1.0" + }, + "peerDependencies": { + "@typechain/ethers-v6": "^0.5.1", + "ethers": "^6.1.0", + "hardhat": "^2.9.9", + "typechain": "^8.3.2" + } + }, + "node_modules/@typechain/hardhat/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "peer": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@types/bn.js": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", + "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/chai": { + "version": "4.3.16", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", + "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==", + "dev": true, + "peer": true + }, + "node_modules/@types/chai-as-promised": { + "version": "7.1.8", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz", + "integrity": "sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/chai": "*" + } + }, + "node_modules/@types/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "peer": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==" + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true, + "peer": true + }, + "node_modules/@types/mocha": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.7.tgz", + "integrity": "sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==", + "dev": true, + "peer": true + }, + "node_modules/@types/node": { + "version": "20.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", + "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", + "dev": true, + "peer": true + }, + "node_modules/@types/qs": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "dev": true, + "peer": true + }, + "node_modules/@types/secp256k1": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", + "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", + "dev": true, + "peer": true + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "devOptional": true, + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "devOptional": true, + "peer": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "engines": { + "node": ">=0.3.0" + } + }, + "node_modules/aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==" + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", + "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "devOptional": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/amazon-cognito-identity-js": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/amazon-cognito-identity-js/-/amazon-cognito-identity-js-6.3.12.tgz", + "integrity": "sha512-s7NKDZgx336cp+oDeUtB2ZzT8jWJp/v2LWuYl+LQtMEODe22RF1IJ4nRiDATp+rp1pTffCZcm44Quw4jx2bqNg==", + "dependencies": { + "@aws-crypto/sha256-js": "1.2.2", + "buffer": "4.9.2", + "fast-base64-decode": "^1.0.0", + "isomorphic-unfetch": "^3.0.0", + "js-cookie": "^2.2.1" + } + }, + "node_modules/amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.4.2" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/antlr4ts": { + "version": "0.5.0-alpha.4", + "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", + "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", + "dev": true, + "peer": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "devOptional": true, + "peer": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "peer": true + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", + "dev": true, + "peer": true + }, + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "dependencies": { + "retry": "0.13.1" + } + }, + "node_modules/async-retry/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", + "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", + "dev": true, + "peer": true + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, + "node_modules/boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true, + "peer": true + }, + "node_modules/cbor": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", + "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", + "devOptional": true, + "dependencies": { + "nofilter": "^3.1.0" + }, + "engines": { + "node": ">=12.19" + } + }, + "node_modules/chai": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "dev": true, + "peer": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chai-as-promised": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.2.tgz", + "integrity": "sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==", + "dev": true, + "peer": true, + "dependencies": { + "check-error": "^1.0.2" + }, + "peerDependencies": { + "chai": ">= 2.1.2 < 6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "peer": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table3": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", + "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", + "dev": true, + "peer": true, + "dependencies": { + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "colors": "^1.1.2" + } + }, + "node_modules/cli-table3/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-table3/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-table3/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "peer": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-table3/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==" + }, + "node_modules/command-line-args": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", + "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", + "dev": true, + "peer": true, + "dependencies": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/command-line-usage": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz", + "integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==", + "dev": true, + "peer": true, + "dependencies": { + "array-back": "^4.0.2", + "chalk": "^2.4.2", + "table-layout": "^1.0.2", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/command-line-usage/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage/node_modules/array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/command-line-usage/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/command-line-usage/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "peer": true + }, + "node_modules/command-line-usage/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/command-line-usage/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/compare-versions": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", + "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "peer": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "peer": true + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "peer": true + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "devOptional": true, + "peer": true + }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/death": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", + "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", + "dev": true, + "peer": true + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "peer": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "peer": true + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/difflib": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", + "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", + "dev": true, + "peer": true, + "dependencies": { + "heap": ">= 0.2.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "peer": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", + "dev": true, + "peer": true, + "dependencies": { + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=0.12.0" + }, + "optionalDependencies": { + "source-map": "~0.2.0" + } + }, + "node_modules/esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", + "dev": true, + "peer": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eth-gas-reporter": { + "version": "0.2.27", + "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.27.tgz", + "integrity": "sha512-femhvoAM7wL0GcI8ozTdxfuBtBFJ9qsyIAsmKVjlWAHUbdnnXHt+lKzz/kmldM5lA9jLuNHGwuIxorNpLbR1Zw==", + "dev": true, + "peer": true, + "dependencies": { + "@solidity-parser/parser": "^0.14.0", + "axios": "^1.5.1", + "cli-table3": "^0.5.0", + "colors": "1.4.0", + "ethereum-cryptography": "^1.0.3", + "ethers": "^5.7.2", + "fs-readdir-recursive": "^1.1.0", + "lodash": "^4.17.14", + "markdown-table": "^1.1.3", + "mocha": "^10.2.0", + "req-cwd": "^2.0.0", + "sha1": "^1.1.1", + "sync-request": "^6.0.0" + }, + "peerDependencies": { + "@codechecks/client": "^0.1.0" + }, + "peerDependenciesMeta": { + "@codechecks/client": { + "optional": true + } + } + }, + "node_modules/eth-gas-reporter/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "peer": true + }, + "node_modules/eth-gas-reporter/node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "peer": true, + "dependencies": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "peer": true, + "dependencies": { + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/ethereum-cryptography": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", + "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" + } + }, + "node_modules/eth-gas-reporter/node_modules/ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, + "node_modules/ethereum-bloom-filters": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.1.0.tgz", + "integrity": "sha512-J1gDRkLpuGNvWYzWslBQR9cDV4nd4kfvVTE/Wy4Kkm4yb3EYRSlyi0eB/inTsSTTVyA0+HyzHgbr95Fn/Z1fSw==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "^1.4.0" + } + }, + "node_modules/ethereum-bloom-filters/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethereumjs-abi": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", + "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", + "dependencies": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ethereumjs-abi/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ethereumjs-abi/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ethereumjs-util": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", + "dependencies": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ethers": { + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.13.1.tgz", + "integrity": "sha512-hdJ2HOxg/xx97Lm9HdCWk949BfYqYWpyw4//78SiwOLgASyfrNszfMUNB2joKjvGUdwhHfaiMMFFwacVVoLR9A==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/ethers-io/" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@adraffy/ens-normalize": "1.10.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "18.15.13", + "aes-js": "4.0.0-beta.5", + "tslib": "2.4.0", + "ws": "8.17.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/ethers/node_modules/@types/node": { + "version": "18.15.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", + "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==" + }, + "node_modules/ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", + "dev": true, + "peer": true, + "dependencies": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true, + "peer": true + }, + "node_modules/ethjs-util": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", + "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", + "dependencies": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/fast-base64-decode": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz", + "integrity": "sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "devOptional": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "peer": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "peer": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "peer": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dev": true, + "peer": true, + "dependencies": { + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fp-ts": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", + "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==" + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true, + "peer": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ghost-testrpc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", + "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", + "dev": true, + "peer": true, + "dependencies": { + "chalk": "^2.4.2", + "node-emoji": "^1.10.0" + }, + "bin": { + "testrpc-sc": "index.js" + } + }, + "node_modules/ghost-testrpc/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ghost-testrpc/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ghost-testrpc/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/ghost-testrpc/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "peer": true + }, + "node_modules/ghost-testrpc/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ghost-testrpc/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ghost-testrpc/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "peer": true, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "peer": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "peer": true, + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/handlebars/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hardhat": { + "version": "2.22.6", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.22.6.tgz", + "integrity": "sha512-abFEnd9QACwEtSvZZGSmzvw7N3zhQN1cDKz5SLHAupfG24qTHofCjqvD5kT5Wwsq5XOL0ON1Mq5rr4v0XX5ciw==", + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@metamask/eth-sig-util": "^4.0.0", + "@nomicfoundation/edr": "^0.4.1", + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-tx": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "@nomicfoundation/solidity-analyzer": "^0.1.0", + "@sentry/node": "^5.18.1", + "@types/bn.js": "^5.1.0", + "@types/lru-cache": "^5.1.0", + "adm-zip": "^0.4.16", + "aggregate-error": "^3.0.0", + "ansi-escapes": "^4.3.0", + "boxen": "^5.1.2", + "chalk": "^2.4.2", + "chokidar": "^3.4.0", + "ci-info": "^2.0.0", + "debug": "^4.1.1", + "enquirer": "^2.3.0", + "env-paths": "^2.2.0", + "ethereum-cryptography": "^1.0.3", + "ethereumjs-abi": "^0.6.8", + "find-up": "^2.1.0", + "fp-ts": "1.19.3", + "fs-extra": "^7.0.1", + "glob": "7.2.0", + "immutable": "^4.0.0-rc.12", + "io-ts": "1.10.4", + "keccak": "^3.0.2", + "lodash": "^4.17.11", + "mnemonist": "^0.38.0", + "mocha": "^10.0.0", + "p-map": "^4.0.0", + "raw-body": "^2.4.1", + "resolve": "1.17.0", + "semver": "^6.3.0", + "solc": "0.8.26", + "source-map-support": "^0.5.13", + "stacktrace-parser": "^0.1.10", + "tsort": "0.0.1", + "undici": "^5.14.0", + "uuid": "^8.3.2", + "ws": "^7.4.6" + }, + "bin": { + "hardhat": "internal/cli/bootstrap.js" + }, + "peerDependencies": { + "ts-node": "*", + "typescript": "*" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/hardhat-gas-reporter": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.10.tgz", + "integrity": "sha512-02N4+So/fZrzJ88ci54GqwVA3Zrf0C9duuTyGt0CFRIh/CdNwbnTgkXkRfojOMLBQ+6t+lBIkgbsOtqMvNwikA==", + "dev": true, + "peer": true, + "dependencies": { + "array-uniq": "1.0.3", + "eth-gas-reporter": "^0.2.25", + "sha1": "^1.1.1" + }, + "peerDependencies": { + "hardhat": "^2.0.2" + } + }, + "node_modules/hardhat/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/hardhat/node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/hardhat/node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/hardhat/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/hardhat/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/hardhat/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/hardhat/node_modules/ethereum-cryptography": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", + "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", + "dependencies": { + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" + } + }, + "node_modules/hardhat/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/hardhat/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/hardhat/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/hardhat/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, + "node_modules/heap": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", + "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", + "dev": true, + "peer": true + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "dev": true, + "peer": true, + "dependencies": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "^10.0.3" + } + }, + "node_modules/http-response-object/node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", + "dev": true, + "peer": true + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/immer": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.2.tgz", + "integrity": "sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==", + "dev": true, + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/immutable": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz", + "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==" + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "peer": true + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/io-ts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", + "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", + "dependencies": { + "fp-ts": "^1.0.0" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "peer": true + }, + "node_modules/isomorphic-unfetch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz", + "integrity": "sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==", + "dependencies": { + "node-fetch": "^2.6.1", + "unfetch": "^4.2.0" + } + }, + "node_modules/js-cookie": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", + "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==" + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "devOptional": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "peer": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "peer": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonschema": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", + "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/keccak": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", + "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "peer": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true, + "peer": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "devOptional": true, + "peer": true + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "devOptional": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "peer": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lru_map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", + "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==" + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "devOptional": true, + "peer": true + }, + "node_modules/markdown-table": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", + "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", + "dev": true, + "peer": true + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micro-ftch": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", + "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==", + "dev": true, + "peer": true + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "peer": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mnemonist": { + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", + "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", + "dependencies": { + "obliterator": "^2.0.0" + } + }, + "node_modules/mocha": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.6.0.tgz", + "integrity": "sha512-hxjt4+EEB0SA0ZDygSS015t65lJw/I2yRCS3Ae+SJ5FrbzrXgfYwJr96f0OvIXdj7h4lv/vLCrH3rkiuizFSvw==", + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/mocha/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/ndjson": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ndjson/-/ndjson-2.0.0.tgz", + "integrity": "sha512-nGl7LRGrzugTtaFcJMhLbpzJM6XdivmbkdlaGcrk/LXg2KL/YBC6z1g70xh0/al+oFuVFP8N8kiWRucmeEH/qQ==", + "dev": true, + "peer": true, + "dependencies": { + "json-stringify-safe": "^5.0.1", + "minimist": "^1.2.5", + "readable-stream": "^3.6.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "ndjson": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "peer": true + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node_modules/node-emoji": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "dev": true, + "peer": true, + "dependencies": { + "lodash": "^4.17.21" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", + "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/nofilter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", + "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", + "engines": { + "node": ">=12.19" + } + }, + "node_modules/nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", + "dev": true, + "peer": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", + "dev": true, + "peer": true, + "dependencies": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/number-to-bn/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true, + "peer": true + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obliterator": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", + "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "peer": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ordinal": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ordinal/-/ordinal-1.0.3.tgz", + "integrity": "sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ==", + "dev": true, + "peer": true + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "engines": { + "node": ">=4" + } + }, + "node_modules/parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", + "dev": true, + "peer": true + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "peer": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "peer": true + }, + "node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "dev": true, + "peer": true, + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "peer": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/proper-lockfile": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", + "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", + "dependencies": { + "graceful-fs": "^4.2.4", + "retry": "^0.12.0", + "signal-exit": "^3.0.2" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "devOptional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.2.tgz", + "integrity": "sha512-x+NLUpx9SYrcwXtX7ob1gnkSems4i/mGZX5SlYxwIau6RrUSODO89TR/XDGGpn5RPWSYIB+aSfuSlV5+CmbTBg==", + "dev": true, + "peer": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "peer": true + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dev": true, + "peer": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "dev": true, + "peer": true, + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/reduce-flatten": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", + "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/req-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", + "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", + "dev": true, + "peer": true, + "dependencies": { + "req-from": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/req-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", + "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", + "dev": true, + "peer": true, + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "peer": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "dependencies": { + "bn.js": "^5.2.0" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "peer": true, + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-array-concat/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sc-istanbul": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", + "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", + "dev": true, + "peer": true, + "dependencies": { + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "istanbul": "lib/cli.js" + } + }, + "node_modules/sc-istanbul/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "peer": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/sc-istanbul/node_modules/glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "peer": true, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/sc-istanbul/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sc-istanbul/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "peer": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/sc-istanbul/node_modules/js-yaml/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "peer": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sc-istanbul/node_modules/resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", + "dev": true, + "peer": true + }, + "node_modules/sc-istanbul/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, + "node_modules/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "hasInstallScript": true, + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/sha1": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", + "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", + "dev": true, + "peer": true, + "dependencies": { + "charenc": ">= 0.0.1", + "crypt": ">= 0.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dev": true, + "peer": true, + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "peer": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "devOptional": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/solc": { + "version": "0.8.26", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.8.26.tgz", + "integrity": "sha512-yiPQNVf5rBFHwN6SIf3TUUvVAFKcQqmSUFeq+fb6pNRCo0ZCgpYOZDi3BVoezCPIAcKrVYd/qXlBLUP9wVrZ9g==", + "dependencies": { + "command-exists": "^1.2.8", + "commander": "^8.1.0", + "follow-redirects": "^1.12.1", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "bin": { + "solcjs": "solc.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/solc/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/solidity-ast": { + "version": "0.4.56", + "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.56.tgz", + "integrity": "sha512-HgmsA/Gfklm/M8GFbCX/J1qkVH0spXHgALCNZ8fA8x5X+MFdn/8CP2gr5OVyXjXw6RZTPC/Sxl2RUDQOXyNMeA==", + "dependencies": { + "array.prototype.findlast": "^1.2.2" + } + }, + "node_modules/solidity-coverage": { + "version": "0.8.12", + "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.12.tgz", + "integrity": "sha512-8cOB1PtjnjFRqOgwFiD8DaUsYJtVJ6+YdXQtSZDrLGf8cdhhh8xzTtGzVTGeBf15kTv0v7lYPJlV/az7zLEPJw==", + "dev": true, + "peer": true, + "dependencies": { + "@ethersproject/abi": "^5.0.9", + "@solidity-parser/parser": "^0.18.0", + "chalk": "^2.4.2", + "death": "^1.1.0", + "difflib": "^0.2.4", + "fs-extra": "^8.1.0", + "ghost-testrpc": "^0.0.2", + "global-modules": "^2.0.0", + "globby": "^10.0.1", + "jsonschema": "^1.2.4", + "lodash": "^4.17.21", + "mocha": "^10.2.0", + "node-emoji": "^1.10.0", + "pify": "^4.0.1", + "recursive-readdir": "^2.2.2", + "sc-istanbul": "^0.4.5", + "semver": "^7.3.4", + "shelljs": "^0.8.3", + "web3-utils": "^1.3.6" + }, + "bin": { + "solidity-coverage": "plugins/bin.js" + }, + "peerDependencies": { + "hardhat": "^2.11.0" + } + }, + "node_modules/solidity-coverage/node_modules/@solidity-parser/parser": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.18.0.tgz", + "integrity": "sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA==", + "dev": true, + "peer": true + }, + "node_modules/solidity-coverage/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solidity-coverage/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solidity-coverage/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/solidity-coverage/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "peer": true + }, + "node_modules/solidity-coverage/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/solidity-coverage/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/solidity-coverage/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/solidity-coverage/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/solidity-coverage/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/solidity-coverage/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solidity-coverage/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "amdefine": ">=0.0.4" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "peer": true, + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "peer": true + }, + "node_modules/stacktrace-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", + "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", + "dependencies": { + "type-fest": "^0.7.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stacktrace-parser/node_modules/type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stl-contracts": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/stl-contracts/-/stl-contracts-2.5.1.tgz", + "integrity": "sha512-fkIq5BPq2/MTkQEDgXRM5WtrpQXqar3lDtha7N446UoCvNWP2isKfcRJ0RKatyMegGvRK1yWugDbbR3OGZiGXg==" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-format": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-format/-/string-format-2.0.0.tgz", + "integrity": "sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==", + "dev": true, + "peer": true + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "dev": true, + "peer": true, + "dependencies": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "dev": true, + "peer": true, + "dependencies": { + "get-port": "^3.1.0" + } + }, + "node_modules/table": { + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", + "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "devOptional": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table-layout": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", + "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", + "dev": true, + "peer": true, + "dependencies": { + "array-back": "^4.0.1", + "deep-extend": "~0.6.0", + "typical": "^5.2.0", + "wordwrapjs": "^4.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/table-layout/node_modules/array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/table-layout/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "dev": true, + "peer": true, + "dependencies": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/then-request/node_modules/@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", + "dev": true, + "peer": true + }, + "node_modules/then-request/node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dev": true, + "peer": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "peer": true, + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/ts-command-line-args": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz", + "integrity": "sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==", + "dev": true, + "peer": true, + "dependencies": { + "chalk": "^4.1.0", + "command-line-args": "^5.1.1", + "command-line-usage": "^6.1.0", + "string-format": "^2.0.0" + }, + "bin": { + "write-markdown": "dist/write-markdown.js" + } + }, + "node_modules/ts-essentials": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", + "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", + "dev": true, + "peer": true, + "peerDependencies": { + "typescript": ">=3.7.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "devOptional": true, + "peer": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "devOptional": true, + "peer": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "node_modules/tsort": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", + "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==" + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "node_modules/tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "peer": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typechain": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.3.2.tgz", + "integrity": "sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==", + "dev": true, + "peer": true, + "dependencies": { + "@types/prettier": "^2.1.1", + "debug": "^4.3.1", + "fs-extra": "^7.0.0", + "glob": "7.1.7", + "js-sha3": "^0.8.0", + "lodash": "^4.17.15", + "mkdirp": "^1.0.4", + "prettier": "^2.3.1", + "ts-command-line-args": "^2.2.0", + "ts-essentials": "^7.0.1" + }, + "bin": { + "typechain": "dist/cli/cli.js" + }, + "peerDependencies": { + "typescript": ">=4.3.0" + } + }, + "node_modules/typechain/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/typechain/node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/typechain/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/typechain/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "peer": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/typechain/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true, + "peer": true + }, + "node_modules/typescript": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "devOptional": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/uglify-js": { + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz", + "integrity": "sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici": { + "version": "5.28.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", + "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/unfetch": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", + "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "devOptional": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", + "dev": true, + "peer": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "devOptional": true, + "peer": true + }, + "node_modules/web3-utils": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.4.tgz", + "integrity": "sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==", + "dev": true, + "peer": true, + "dependencies": { + "@ethereumjs/util": "^8.1.0", + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereum-cryptography": "^2.1.2", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-utils/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "peer": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "peer": true + }, + "node_modules/wordwrapjs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", + "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", + "dev": true, + "peer": true, + "dependencies": { + "reduce-flatten": "^2.0.0", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/wordwrapjs/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "devOptional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "devOptional": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } } - } } diff --git a/assets/erc-7738/package.json b/assets/erc-7738/package.json index ff6b8f6e8b..734505b483 100644 --- a/assets/erc-7738/package.json +++ b/assets/erc-7738/package.json @@ -1,35 +1,28 @@ { - "name": "hardhat", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "@nomicfoundation/hardhat-ethers": "^3.0.6", - "@openzeppelin/contracts": "^5.0.2", -<<<<<<< HEAD - "@openzeppelin/contracts-upgradeable": "^5.0.2", - "@openzeppelin/hardhat-upgrades": "^3.2.1", - "@openzeppelin/upgrades-core": "^1.35.0", -======= ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - "dotenv": "^16.4.5", - "ethers": "^6.13.1", - "hardhat": "^2.22.6", - "stl-contracts": "^2.5.1" - }, - "devDependencies": { - "@nomicfoundation/hardhat-ignition-ethers": "^0.15.5", -<<<<<<< HEAD - "@nomicfoundation/hardhat-toolbox": "^5.0.0", - "@nomiclabs/hardhat-etherscan": "^3.1.8" -======= - "@nomicfoundation/hardhat-toolbox": "^5.0.0" ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 - } + "name": "hardhat", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@nomicfoundation/hardhat-ethers": "^3.0.6", + "@openzeppelin/contracts": "^5.0.2", + "@openzeppelin/contracts-upgradeable": "^5.0.2", + "@openzeppelin/hardhat-upgrades": "^3.2.1", + "@openzeppelin/upgrades-core": "^1.35.0", + "dotenv": "^16.4.5", + "ethers": "^6.13.1", + "hardhat": "^2.22.6", + "stl-contracts": "^2.5.1" + }, + "devDependencies": { + "@nomicfoundation/hardhat-ignition-ethers": "^0.15.5", + "@nomicfoundation/hardhat-toolbox": "^5.0.0", + "@nomiclabs/hardhat-etherscan": "^3.1.8" + } } diff --git a/assets/erc-7738/scripts/createRegistryEntry.ts b/assets/erc-7738/scripts/createRegistryEntry.ts new file mode 100644 index 0000000000..a5426cb21a --- /dev/null +++ b/assets/erc-7738/scripts/createRegistryEntry.ts @@ -0,0 +1,43 @@ +import dotenv from "dotenv"; +const { ethers, upgrades } = require("hardhat"); +const { getImplementationAddress } = require('@openzeppelin/upgrades-core'); +const { getContractAddress } = require('@ethersproject/address') +dotenv.config(); + +const deployedRegistry = "0x0077380bCDb2717C9640e892B9d5Ee02Bb5e0682"; + +const myNFTContract = ""; // Your NFT contract address here +const myTokenScriptURI = ""; // Your TokenScript URI here, in IPFS format (ipfs://Qm....) or http (eg https://mystorage.com/mytoken1.tsml) + +// Helper script to re-assign ownership of ENS domain to the registry contract +async function main() { + const privateKey: any = process.env.PRIVATE_KEY; + if (!privateKey) { + throw new Error("PRIVATE_KEY not found in .env file"); + } + + const primaryDeployKey = new ethers.Wallet(privateKey, ethers.provider); + console.log(`ADDR: ${primaryDeployKey.address}`); + + const Registry = await ethers.getContractFactory("DecentralisedRegistryNFT", primaryDeployKey); + let registry = Registry.attach(deployedRegistry); + + // now write to contract + await registry.connect(primaryDeployKey).setScriptURI(myNFTContract, [myTokenScriptURI]); + + // read script + let scriptURIArray = await registry.scriptURI(myNFTContract); + + // assume we wrote the first script, our entry will be the first one. If there were previous scripts we need to adjust the array marker + console.log(`Read scriptURI: ${scriptURIArray[0]}`); +} + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); + + + // to run: npx hardhat run .\scripts\createRegistryEntry.ts --network holesky \ No newline at end of file diff --git a/assets/erc-7738/scripts/deploy.ts b/assets/erc-7738/scripts/deploy.ts index 4422dc995e..37ea6300a2 100644 --- a/assets/erc-7738/scripts/deploy.ts +++ b/assets/erc-7738/scripts/deploy.ts @@ -163,10 +163,16 @@ main() }); - // to run: npx hardhat run .\scripts\deploy.ts --network holesky - // to verify logic: npx hardhat verify 0x30Af1aea43490e2F03d4d7eF3116b745D7D58c30 --network holesky - // to verify full: npx hardhat verify 0x0077380bCDb2717C9640e892B9d5Ee02Bb5e0682 --network holesky "ERC-7738 Script Registry", "ERC7738", 0x97b0341BEdbC521778B669550774691918202e65, 0x527E7E85cF60390b56bE953888e0cb036682761B + // to run: npx hardhat run .\scripts\deploy.ts --network mainnet + // to verify logic: npx hardhat verify 0x30Af1aea43490e2F03d4d7eF3116b745D7D58c30 --network mainnet + // to verify full: npx hardhat verify 0x0077380bCDb2717C9640e892B9d5Ee02Bb5e0682 --network mainnet "ERC-7738 Script Registry", "ERC7738", 0x276d7760fA6774E3AE8F8a7446B88fb2479D38aC, 0x527E7E85cF60390b56bE953888e0cb036682761B // verify metadata logic: npx hardhat verify 0x276d7760fA6774E3AE8F8a7446B88fb2479D38aC --network mainnet - // verify ensAssigner logic: npx hardhat verify 0x527E7E85cF60390b56bE953888e0cb036682761B --network mainnet \ No newline at end of file + // verify ensAssigner logic: npx hardhat verify 0x527E7E85cF60390b56bE953888e0cb036682761B --network mainnet + +// npx hardhat verify 0x30Af1aea43490e2F03d4d7eF3116b745D7D58c30 --network arbitrum +// npx hardhat verify 0x276d7760fA6774E3AE8F8a7446B88fb2479D38aC --network arbitrum +// npx hardhat verify 0x97b0341BEdbC521778B669550774691918202e65 --network arbitrum +// npx hardhat verify 0x527E7E85cF60390b56bE953888e0cb036682761B --network arbitrum +// npx hardhat verify 0x0077380bCDb2717C9640e892B9d5Ee02Bb5e0682 --network arbitrum "ERC-7738 Script Registry", "ERC7738", 0x276d7760fA6774E3AE8F8a7446B88fb2479D38aC, 0x527E7E85cF60390b56bE953888e0cb036682761B diff --git a/assets/erc-7738/scripts/upgradeRegistry.ts b/assets/erc-7738/scripts/upgradeRegistry.ts index 14d94c1e58..334ca89223 100644 --- a/assets/erc-7738/scripts/upgradeRegistry.ts +++ b/assets/erc-7738/scripts/upgradeRegistry.ts @@ -43,4 +43,4 @@ main() }); - // to run: npx hardhat run .\scripts\updateRegistry.ts --network holesky \ No newline at end of file + // to run: npx hardhat run .\scripts\upgradeRegistry.ts --network holesky \ No newline at end of file diff --git a/assets/erc-7738/test/DecentralisedRegistry.test.ts b/assets/erc-7738/test/DecentralisedRegistry.test.ts index b2fca1c075..f3c1e45ead 100644 --- a/assets/erc-7738/test/DecentralisedRegistry.test.ts +++ b/assets/erc-7738/test/DecentralisedRegistry.test.ts @@ -15,19 +15,11 @@ async function deployInitialFixture() { // Contracts are deployed using the first signer/account by default const [owner, otherAccount, otherAccount2, otherAccount3, otherAccount4] = await ethers.getSigners(); -<<<<<<< HEAD const ExampleNFT = (await ethers.getContractFactory("ExampleNFT")).connect( owner ); const exampleNFT = await ExampleNFT.deploy(); await exampleNFT.waitForDeployment(); -======= - const StakingToken = (await ethers.getContractFactory("StakingToken")).connect( - owner - ); - const stakingToken = await StakingToken.deploy(); - await stakingToken.waitForDeployment(); ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 //Deploy registry contract const Registry = (await ethers.getContractFactory("DecentralisedRegistry")).connect( @@ -42,11 +34,7 @@ async function deployInitialFixture() { otherAccount2, otherAccount3, otherAccount4, -<<<<<<< HEAD exampleNFT, -======= - stakingToken, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 registry, }; } @@ -60,21 +48,12 @@ describe("DecentralisedRegistry", function () { otherAccount2, otherAccount3, otherAccount4, -<<<<<<< HEAD exampleNFT, registry } = await loadFixture(deployInitialFixture); await expect(exampleNFT.connect(owner).safeMint()) .to.emit(exampleNFT, "Transfer") -======= - stakingToken, - registry - } = await loadFixture(deployInitialFixture); - - await expect(stakingToken.connect(owner).safeMint()) - .to.emit(stakingToken, "Transfer") ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 .withArgs(ethers.ZeroAddress, owner.address, 1); const scriptURI = [scriptURI1]; @@ -83,7 +62,6 @@ describe("DecentralisedRegistry", function () { const origScript = [origScriptURI]; //set scriptURI -<<<<<<< HEAD await registry.connect(otherAccount2).setScriptURI(exampleNFT.target, scriptURI); //console.log(`Current ScriptURI = ${await registry.scriptURI(exampleNFT.target)}`); @@ -104,28 +82,6 @@ describe("DecentralisedRegistry", function () { await registry.connect(owner).setScriptURI(exampleNFT.target, origScript); let finalScriptURI = await registry.scriptURI(exampleNFT.target); -======= - await registry.connect(otherAccount2).setScriptURI(stakingToken.target, scriptURI); - - //console.log(`Current ScriptURI = ${await registry.scriptURI(stakingToken.target)}`); - - expect((await registry.scriptURI(stakingToken.target)).toString()).to.be.equal(scriptURI.toString()); - - //attempt to set Script URI with delegate account - await registry.connect(otherAccount).setScriptURI(stakingToken.target, scriptURITest2); - - //now dump the current full scriptURI - //console.log(`Current ScriptURI = ${await registry.scriptURI(stakingToken.target)}`); - - await registry.connect(otherAccount3).setScriptURI(stakingToken.target, scriptURITest3); - - //console.log(`Current ScriptURI = ${await registry.scriptURI(stakingToken.target)}`); - - //now owner writes, should come first - await registry.connect(owner).setScriptURI(stakingToken.target, origScript); - - let finalScriptURI = await registry.scriptURI(stakingToken.target); ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 //console.log(`Current ScriptURI = ${finalScriptURI}`); @@ -136,22 +92,14 @@ describe("DecentralisedRegistry", function () { expect(firstScriptURI).to.equal(origScriptURI); //add another entry -<<<<<<< HEAD await registry.connect(otherAccount4).setScriptURI(exampleNFT.target, [scriptURI4, scriptURI1, scriptURI2]); //owner script should still be first finalScriptURI = await registry.scriptURI(exampleNFT.target); -======= - await registry.connect(otherAccount4).setScriptURI(stakingToken.target, [scriptURI4, scriptURI1, scriptURI2]); - - //owner script should still be first - finalScriptURI = await registry.scriptURI(stakingToken.target); ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 firstScriptURI = finalScriptURI[0]; expect(firstScriptURI).to.equal(origScriptURI); //attempt to write zero sized scriptURI -<<<<<<< HEAD await expect(registry.connect(otherAccount4).setScriptURI(exampleNFT.target, [])) .to.revertedWith("> 0 entries required in scriptURIList"); @@ -166,27 +114,10 @@ describe("DecentralisedRegistry", function () { //now add back await registry.connect(otherAccount3).setScriptURI(exampleNFT.target, [scriptURI4, scriptURI1, scriptURI2]); finalScriptURI = await registry.scriptURI(exampleNFT.target); -======= - await expect(registry.connect(otherAccount4).setScriptURI(stakingToken.target, [])) - .to.revertedWith("> 0 entries required in scriptURIList"); - - //remove an entry - await registry.connect(otherAccount4).setScriptURI(stakingToken.target, [""]); - //console.log(`Current ScriptURI = ${await registry.scriptURI(stakingToken.target)}`); - - //and another - await registry.connect(otherAccount3).setScriptURI(stakingToken.target, [""]); - //console.log(`Current ScriptURI = ${await registry.scriptURI(stakingToken.target)}`); - - //now add back - await registry.connect(otherAccount3).setScriptURI(stakingToken.target, [scriptURI4, scriptURI1, scriptURI2]); - finalScriptURI = await registry.scriptURI(stakingToken.target); ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 //console.log(`Current ScriptURI = ${finalScriptURI}`); //check final return, should be: let correctFinal = [origScriptURI, scriptURI1, scriptURI2, scriptURI4, scriptURI1, scriptURI2, ""]; -<<<<<<< HEAD expect((await registry.scriptURI(exampleNFT.target)).toString()).to.be.equal(correctFinal.toString()); checkPageSize(2, correctFinal, registry, exampleNFT); @@ -197,18 +128,6 @@ describe("DecentralisedRegistry", function () { async function checkPageSize(pageSize: number, correctFinal: string[], registry: any, exampleNFT: any) { -======= - expect((await registry.scriptURI(stakingToken.target)).toString()).to.be.equal(correctFinal.toString()); - - checkPageSize(2, correctFinal, registry, stakingToken); - checkPageSize(3, correctFinal, registry, stakingToken); - checkPageSize(1, correctFinal, registry, stakingToken); - checkPageSize(500, correctFinal, registry, stakingToken); - }); - - - async function checkPageSize(pageSize: number, correctFinal: string[], registry: any, stakingToken: any) { ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 const totalPages = Math.ceil(correctFinal.length / pageSize); for (let page = 1; page <= totalPages; page++) { @@ -223,11 +142,7 @@ describe("DecentralisedRegistry", function () { } } -<<<<<<< HEAD let contractReturn = await registry.scriptURI(exampleNFT.target, page, pageSize); -======= - let contractReturn = await registry.scriptURI(stakingToken.target, page, pageSize); ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 //console.log(`Actual return = ${contractReturn} Expected = ${expected}`); expect(contractReturn.toString()).to.be.equal(expected.toString()); } diff --git a/assets/erc-7738/test/PermissionedRegistry.test.ts b/assets/erc-7738/test/PermissionedRegistry.test.ts index 3886b62927..7739524190 100644 --- a/assets/erc-7738/test/PermissionedRegistry.test.ts +++ b/assets/erc-7738/test/PermissionedRegistry.test.ts @@ -11,19 +11,11 @@ async function deployInitialFixture() { // Contracts are deployed using the first signer/account by default const [owner, otherAccount, otherAccount2] = await ethers.getSigners(); -<<<<<<< HEAD const ExampleNFT = (await ethers.getContractFactory("ExampleNFT")).connect( owner ); const exampleNFT = await ExampleNFT.deploy(); await exampleNFT.waitForDeployment(); -======= - const StakingToken = (await ethers.getContractFactory("StakingToken")).connect( - owner - ); - const stakingToken = await StakingToken.deploy(); - await stakingToken.waitForDeployment(); ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 //Deploy registry contract const Registry = (await ethers.getContractFactory("DecentralisedRegistryPermissioned")).connect( @@ -36,11 +28,7 @@ async function deployInitialFixture() { owner, otherAccount, otherAccount2, -<<<<<<< HEAD exampleNFT, -======= - stakingToken, ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 registry, }; } @@ -52,7 +40,6 @@ describe("Decentralised Permissioned Registry", function () { owner, otherAccount, otherAccount2, -<<<<<<< HEAD exampleNFT, registry } = await loadFixture(deployInitialFixture); @@ -68,29 +55,11 @@ describe("Decentralised Permissioned Registry", function () { await registry.connect(owner).registerOwner(exampleNFT.target); await expect(registry.connect(otherAccount).registerOwner(exampleNFT.target)) -======= - stakingToken, - registry - } = await loadFixture(deployInitialFixture); - - await expect(stakingToken.connect(owner).safeMint()) - .to.emit(stakingToken, "Transfer") - .withArgs(ethers.ZeroAddress, owner.address, 1); - - //initially register with otherAccount - await registry.connect(otherAccount).registerOwner(stakingToken.target); - - //owner can override - await registry.connect(owner).registerOwner(stakingToken.target); - - await expect(registry.connect(otherAccount).registerOwner(stakingToken.target)) ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 .to.revertedWith("Not authorized"); const scriptURI = [scriptURI1]; //set scriptURI -<<<<<<< HEAD await expect(registry.connect(otherAccount).setScriptURI(exampleNFT.target, scriptURI)) .to.revertedWith("Not authorized"); await expect(registry.connect(otherAccount2).setScriptURI(exampleNFT.target, scriptURI)) @@ -108,32 +77,12 @@ describe("Decentralised Permissioned Registry", function () { //attempt to set Script URI with delegate account await registry.connect(otherAccount2).setScriptURI(exampleNFT.target, scriptURI); -======= - await expect(registry.connect(otherAccount).setScriptURI(stakingToken.target, scriptURI)) - .to.revertedWith("Not authorized"); - await expect(registry.connect(otherAccount2).setScriptURI(stakingToken.target, scriptURI)) - .to.revertedWith("Not authorized"); - - await registry.connect(owner).setScriptURI(stakingToken.target, scriptURI); - - expect((await registry.scriptURI(stakingToken.target)).toString()).to.be.equal(scriptURI.toString()); - - //add delegate - await expect(registry.connect(otherAccount).addDelegateSigner(stakingToken.target, otherAccount2)) - .to.revertedWith("Contract Owner only"); - - await registry.connect(owner).addDelegateSigner(stakingToken.target, otherAccount2); - - //attempt to set Script URI with delegate account - await registry.connect(otherAccount2).setScriptURI(stakingToken.target, scriptURI); ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 // Verify script signing operation. // Assume that a process has come back from evaluating the address of a TokenScript and needs to verify if the // key is allowed to validate the contract let ecRecoverSigningKey = otherAccount2.address; -<<<<<<< HEAD expect((await registry.isDelegateOrOwner(exampleNFT.target, otherAccount.address))) .to.be.equal(false); @@ -156,30 +105,6 @@ describe("Decentralised Permissioned Registry", function () { .to.be.equal(false); expect((await registry.isDelegateOrOwner(exampleNFT.target, owner.address))) -======= - expect((await registry.isDelegateOrOwner(stakingToken.target, otherAccount.address))) - .to.be.equal(false); - - expect((await registry.isDelegateOrOwner(stakingToken.target, ecRecoverSigningKey))) - .to.be.equal(true); - - expect((await registry.isDelegateOrOwner(stakingToken.target, owner.address))) - .to.be.equal(true); - - // revoke - await expect(registry.connect(otherAccount2).revokeDelegateSigner(stakingToken.target, otherAccount2)) - .to.revertedWith("Contract Owner only"); - - await registry.connect(owner).revokeDelegateSigner(stakingToken.target, otherAccount2); - - await expect(registry.connect(otherAccount2).setScriptURI(stakingToken.target, scriptURI)) - .to.revertedWith("Not authorized"); - - expect((await registry.isDelegateOrOwner(stakingToken.target, ecRecoverSigningKey))) - .to.be.equal(false); - - expect((await registry.isDelegateOrOwner(stakingToken.target, owner.address))) ->>>>>>> 4a582f5016fd4065b7a851531340835b2bad9bb6 .to.be.equal(true); }); diff --git a/assets/erc-7738/tokenscript/onboard.html b/assets/erc-7738/tokenscript/onboard.html index f5e19e4f6b..e0fb20d670 100644 --- a/assets/erc-7738/tokenscript/onboard.html +++ b/assets/erc-7738/tokenscript/onboard.html @@ -119,7 +119,7 @@

ScriptURI

try { let checksumAddr = ethers.getAddress(value); const result = await provider.getCode(checksumAddr); - if (result.startsWith("0x60")) { + if (result.length > 2) { // If code returned is more than '0x' it's a contract of some kind errorText.style.display = 'none'; successIcon.style.display = 'inline'; return checksumAddr; diff --git a/assets/erc-7738/tokenscript/out/tokenscript.tsml b/assets/erc-7738/tokenscript/out/tokenscript.tsml index 6b7762175c..c52e9fc428 100644 --- a/assets/erc-7738/tokenscript/out/tokenscript.tsml +++ b/assets/erc-7738/tokenscript/out/tokenscript.tsml @@ -1042,7 +1042,7 @@ try { let checksumAddr = ethers.getAddress(value); const result = await provider.getCode(checksumAddr); - if (result.startsWith("0x60")) { + if (result.length > 2) { // If code returned is more than '0x' it's a contract of some kind errorText.style.display = 'none'; successIcon.style.display = 'inline'; return checksumAddr; From 2d317db96fde85d5025cca90e797ea27c7bb68aa Mon Sep 17 00:00:00 2001 From: Gavin Date: Thu, 24 Oct 2024 23:04:27 +0800 Subject: [PATCH 28/46] Update ERC-5625: Move to Last Call Merged by EIP-Bot. --- ERCS/erc-5625.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ERCS/erc-5625.md b/ERCS/erc-5625.md index dc480c8b37..f577eaa7fe 100644 --- a/ERCS/erc-5625.md +++ b/ERCS/erc-5625.md @@ -2,9 +2,10 @@ eip: 5625 title: NFT Metadata JSON Schema dStorage Extension description: Add a dStorage property to non-fungible tokens (NFTs) metadata JSON schema to provide decentralized storage information of NFT assets -author: Gavin Fu (@gavfu) +author: Gavin Fu (@gavfu), Leo Wang (@wanglie1986), Bova Chen (@appoipp), Guang Han (@pangwa) discussions-to: https://ethereum-magicians.org/t/eip-5625-nft-metadata-json-schema-dstorage-extension/10754 -status: Review +status: Last Call +last-call-deadline: 2024-11-07 type: Standards Track category: ERC created: 2022-09-08 @@ -178,8 +179,8 @@ This EIP is backward compatible with [EIP-721](./eip-721.md) and [EIP-1155](./e ## Security Considerations -Needs discussion. +This EIP does not introduce any new security risks or vulnerabilities, as the `dStorage` property is only an informational field of the Metadata JSON file returned by [EIP-721](./eip-721.md) and [EIP-1155](./eip-1155.md) smart contracts. It does not affect the execution or validity of NFT transactions. ## Copyright -Copyright and related rights waived via [CC0](../LICENSE.md). \ No newline at end of file +Copyright and related rights waived via [CC0](../LICENSE.md). From a467189c77fb7eb9a8e9a0dd9ca002f131660462 Mon Sep 17 00:00:00 2001 From: Mizuki <285361+eseiker@users.noreply.github.com> Date: Mon, 28 Oct 2024 03:49:48 +0900 Subject: [PATCH 29/46] Update ERC-7562: Fix typo in section `OP-062` Merged by EIP-Bot. --- ERCS/erc-7562.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7562.md b/ERCS/erc-7562.md index dc5ae9c046..10e32690ca 100644 --- a/ERCS/erc-7562.md +++ b/ERCS/erc-7562.md @@ -190,7 +190,7 @@ To help make sense of these params, note that a malicious paymaster can at most * **[OP-062]** Precompiles: * Only allow known accepted precompiles on the network, that do not access anything in the blockchain state or environment. * The core precompiles 0x1 .. 0x9 - * The RIP-7212 sec256r1 precompile, on networks that accepted it. + * The RIP-7212 secp256r1 precompile, on networks that accepted it. * **[OP-070]** Transient Storage slots defined in [EIP-1153](./eip-1153) and accessed using `TLOAD` (`0x5c`) and `TSTORE` (`0x5d`) opcodes are treated exactly like persistent storage (SLOAD/SSTORE). * **[OP-080]** `BALANCE` (`0x31`) and `SELFBALANCE` (`0x47`) are allowed only from a staked entity, else they are blocked. From 324e0b7e1dc56f1366bccf55740fb65ac67efd5f Mon Sep 17 00:00:00 2001 From: Vectorized Date: Mon, 28 Oct 2024 13:31:21 +0800 Subject: [PATCH 30/46] Update ERC-7739: Update ERC-7739 Merged by EIP-Bot. --- ERCS/erc-7739.md | 91 +++++++------- .../erc-7739/contracts/accounts/ERC1271.sol | 119 ++++++++++-------- 2 files changed, 111 insertions(+), 99 deletions(-) diff --git a/ERCS/erc-7739.md b/ERCS/erc-7739.md index f4d4c86710..edc581a536 100644 --- a/ERCS/erc-7739.md +++ b/ERCS/erc-7739.md @@ -2,7 +2,7 @@ eip: 7739 title: Readable Typed Signatures for Smart Accounts description: A defensive rehashing scheme which prevents signature replays across smart accounts and preserves the readability of the signed contents -author: vectorized (@vectorized), Sihoon Lee (@push0ebp), Francisco Giordano (@frangio), Im Juno (@junomonster), howydev (@howydev), 0xcuriousapple (@0xcuriousapple) +author: vectorized (@vectorized), Sihoon Lee (@push0ebp), Francisco Giordano (@frangio), Hadrien Croubois (@Amxx), Ernesto García (@ernestognw), Im Juno (@junomonster), howydev (@howydev), Atarpara (@Atarpara), 0xcuriousapple (@0xcuriousapple) discussions-to: https://ethereum-magicians.org/t/erc-7739-readable-typed-signatures-for-smart-accounts/20513 status: Draft type: Standards Track @@ -55,7 +55,7 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S ### Overview -Compliant smart accounts MUST implement the following dependencies: +The following dependencies are REQUIRED: - [EIP-712](./eip-712.md) Typed structured data hashing and signing. Provides the relevant typed data hashing logic internally, which is required to construct the final hashes. @@ -84,8 +84,7 @@ keccak256(\x19\x01 ‖ APP_DOMAIN_SEPARATOR ‖ version: eip712Domain().version, chainId: eip712Domain().chainId, verifyingContract: eip712Domain().verifyingContract, - salt: eip712Domain().salt, - extensions: eip712Domain().extensions + salt: eip712Domain().salt })) ) ``` @@ -112,8 +111,7 @@ finalTypedDataSignHash = keccak256(bytes(eip712Domain().version)), uint256(eip712Domain().chainId), uint256(uint160(eip712Domain().verifyingContract)), - bytes32(eip712Domain().salt), - keccak256(abi.encodePacked(eip712Domain().extensions)) + bytes32(eip712Domain().salt) ) ) ) @@ -127,23 +125,21 @@ typedDataSignTypehash = keccak256( abi.encodePacked( "TypedDataSign(", - contentsTypeName, " contents", - "bytes1 fields,", + contentsName, " contents,", "string name,", "string version,", "uint256 chainId,", "address verifyingContract,", - "bytes32 salt,", - "uint256[] extensions", + "bytes32 salt" ")", contentsType ) ); ``` -If `contentsType` is `"Mail(address from,address to,string message)"`, then `contentsTypeName` will be `"Mail"`. +If `contentsType` is `"Mail(address from,address to,string message)"`, then `contentsName` will be `"Mail"`. -The `contentsTypeName` is the substring of `contentsType` up to (excluding) the first instance of `"("`: +The `contentsName` is the substring of `contentsType` up to (excluding) the first instance of `"("`: In Solidity, this can be written as: @@ -155,7 +151,7 @@ In Solidity, this can be written as: // `indexOf(string memory subject, string memory search)` // Returns the byte index of the first location of `search` in `subject`, // searching from left to right. Returns `2**256 - 1` if `search` is not found. -contentsTypeName = +contentsName = LibString.slice( contentsType, 0, // Start byte index. @@ -163,23 +159,30 @@ contentsTypeName = ); ``` -A copy of the `LibString` Solidity library is provided for reference in [`/assets/eip-7739/contracts/utils/LibString.sol`]. +[A copy of the `LibString` Solidity library is provided for completeness](../assets/eip-7739/contracts/utils/LibString.sol). -For safety, smart accounts MUST treat the signature as invalid if any of the following is true: +For safety, it is RECOMMENDED to treat the signature as invalid if any of the following is true: -- `contentsTypeName` is the empty string (i.e. `bytes(contentsTypeName).length == 0`). -- `contentsTypeName` starts with any of the following bytes `abcdefghijklmnopqrstuvwxyz(`. -- `contentsTypeName` contains any of the following bytes `, )\x00`. +- `contentsName` is the empty string (i.e. `bytes(contentsName).length == 0`). +- `contentsName` starts with any of the following bytes `abcdefghijklmnopqrstuvwxyz(`. +- `contentsName` contains any of the following bytes `, )\x00`. #### `TypedDataSign` signature The `signature` passed into `isValidSignature` will be changed to: ``` -originalSignature ‖ APP_DOMAIN_SEPARATOR ‖ contents ‖ contentsType ‖ uint16(contentsType.length) +originalSignature ‖ APP_DOMAIN_SEPARATOR ‖ contents ‖ contentsDescription ‖ uint16(contentsDescription.length) ``` -where `contents` is the bytes32 struct hash of the original struct. +where: + +- `contents` is the bytes32 struct hash of the original struct. +- `contentsDescription` is either: + - `contentsType` (implicit mode), + where `contentsType` starts with `contentsName`. + - `contentsType ‖ contentsName` (explicit mode), + where `contentsType` may not necessarily start with `contentsName`. In Solidity, this can be written as: @@ -189,8 +192,8 @@ signature = bytes(originalSignature), bytes32(APP_DOMAIN_SEPARATOR), bytes32(contents), - bytes(contentsType), - uint16(contentsType.length) + bytes(contentsDescription), + uint16(contentsDescription.length) ); ``` @@ -268,21 +271,11 @@ hash = The `PersonalSign` workflow does not require additional data to be appended to the `signature` passed into `isValidSignature`. -### `supportsNestedTypedDataSign` function for detection +### Support detection -To facilitate automatic detection, smart accounts SHOULD implement the following function: +Smart accounts SHOULD return `bytes4(0x77390001)` for `isValidSignature(0x7739773977397739773977397739773977397739773977397739773977397739, "")` to indicate support for this standard. -```solidity -/// @dev For automatic detection that the smart account supports the nested EIP-712 workflow. -/// By default, it returns `bytes32(bytes4(keccak256("supportsNestedTypedDataSign()")))`, -/// denoting support for the default behavior, as implemented in -/// `_erc1271IsValidSignatureViaNestedEIP712`, which is called in `isValidSignature`. -/// Future extensions should return a different non-zero `result` to denote different behavior. -/// This method intentionally returns bytes32 to allow freedom for future extensions. -function supportsNestedTypedDataSign() public view virtual returns (bytes32 result) { - result = bytes4(0xd620c85a); -} -``` +The magic number `bytes4(0x77390001)` MAY be incremented if this standard gets updated. ### Signature verification workflow deduction @@ -322,23 +315,31 @@ As many developers may not update their applications to support the nested EIP-7 The `typedDataSignTypehash` must be constructed on-the-fly on-chain. This is to enforce that the signed contents will be visible in the signature request, by requiring that `contents` be a user defined type. -The structure is intentionally made flat with the fields of `eip712Domain` to make implementation feasible. Otherwise, smart accounts must implement on-chain lexographical sorting of strings for the struct type names when constructing `typedDataSignTypehash`. +The fields of `eip712Domain` are flattened into the `TypedDataSign` structure instead of being included as a field of type `EIP712Domain` in order to to avoid a conflict with the domain type of the verifying contract in case it's different. -### `supportsNestedTypedDataSign` for detection +The `bytes1 fields` bitmap and `uint256[] extensions` array in [ERC-5267](./eip-5267.md) have been omitted. Differentiating between an absent field versus a zero field (e.g. `bytes32(0)`) offers no additional security benefits for on-chain defensive rehashing. The `extensions` parameter is a list of EIP numbers used for off-chain signaling. -Without this function, this standard will not change the interface of the smart account, as it defines the behavior of `isValidSignature` without adding any new functions. As such, [ERC-165](./eip-165.md) cannot be used. +### `contentsDescription` with implicit and explicit modes -For future extendability, `supportsNestedTypedDataSign` is defined to return a bytes32 as the first word of its returned data. For bytecode compactness and to leave space for bit packing, only the leftmost 4 bytes are set to the function selector of `supportsNestedTypedDataSign`. +When the `contents` structure contains nested types, EIP-712 lexicographical sorting can result in the `contentsName` not being positioned exactly at the start of the `contentsType`. As such, we need the explicit mode. -The `supportsNestedTypedDataSign` function may be extended to return multiple values (e.g. `bytes32 result, bytes memory data`), as long as the first word of the returned data is a bytes32 identifier. This will not change the function selector. +### Support detection with `isValidSignature` + +For easier implementation in modular smart accounts, we have decided to utilize the `isValidSignature` method to return a magic number instead of defining new functions. + +### Rejecting `contentsName` beginning with any lowercase 7-bit ASCII character + +This recommendation is to keep the standard language agnostic and future-proof. Atomic types such as `uint256` may be named differently in other languages (e.g. `u256`). ## Backwards Compatibility -No backwards compatibility issues. +### Detection of previous draft + +In an earlier draft, we have designated a `supportsNestedTypedDataSign()` function for support detection, which returns `bytes4(0xd620c85a)`. ## Reference Implementation -A production ready and optimized reference implementation is provided at [`/assets/eip-7739/contracts/accounts/ERC1271.sol`]. +[A production ready and optimized implementation is provided for reference](../assets/eip-7739/contracts/accounts/ERC1271.sol). It includes relevant complementary features required for safety, flexibility, developer experience, and user experience. @@ -346,13 +347,13 @@ The reference implementation is intentionally not minimalistic. This is to avoid ## Security Considerations -### Rejecting invalid `contentsTypeName` +### Rejecting invalid `contentsName` Current major implementations of `eth_signTypedData` do not sanitize the names of custom types. -A phishing website can craft a `contentsTypeName` with control characters to break out of the `PersonalSign` type encoding, resulting in the wallet client asking the user to sign an opaque hash. +A phishing website can craft a `contentsName` with control characters to break out of the `PersonalSign` type encoding, resulting in the wallet client asking the user to sign an opaque hash. -Requiring on-chain sanitization of `contentsTypeName` will block this phishing attack vector. +Requiring on-chain sanitization of `contentsName` will block this phishing attack vector. ## Copyright diff --git a/assets/erc-7739/contracts/accounts/ERC1271.sol b/assets/erc-7739/contracts/accounts/ERC1271.sol index c28e00ca10..1e20abfa30 100644 --- a/assets/erc-7739/contracts/accounts/ERC1271.sol +++ b/assets/erc-7739/contracts/accounts/ERC1271.sol @@ -27,6 +27,16 @@ abstract contract ERC1271 is EIP712 { virtual returns (bytes4 result) { + // For automatic detection that the smart account supports the nested EIP-712 workflow, + // See: https://eips.ethereum.org/EIPS/eip-7739. + // If `hash` is `0x7739...7739`, returns `bytes4(0x77390001)`. + // The returned number MAY be increased in future ERC7739 versions. + unchecked { + if (signature.length == uint256(0)) { + // Forces the compiler to optimize for smaller bytecode size. + if (uint256(hash) == ~signature.length / 0xffff * 0x7739) return 0x77390001; + } + } bool success = _erc1271IsValidSignature(hash, _erc1271UnwrapSignature(signature)); /// @solidity memory-safe-assembly assembly { @@ -36,16 +46,6 @@ abstract contract ERC1271 is EIP712 { } } - /// @dev For automatic detection that the smart account supports the nested EIP-712 workflow. - /// By default, it returns `bytes32(bytes4(keccak256("supportsNestedTypedDataSign()")))`, - /// denoting support for the default behavior, as implemented in - /// `_erc1271IsValidSignatureViaNestedEIP712`, which is called in `isValidSignature`. - /// Future extensions should return a different non-zero `result` to denote different behavior. - /// This method intentionally returns bytes32 to allow freedom for future extensions. - function supportsNestedTypedDataSign() public view virtual returns (bytes32 result) { - result = bytes4(0xd620c85a); - } - /// @dev Returns the ERC1271 signer. /// Override to return the signer `isValidSignature` checks against. function _erc1271Signer() internal view virtual returns (address); @@ -146,17 +146,22 @@ abstract contract ERC1271 is EIP712 { /// version: keccak256(bytes(eip712Domain().version)), /// chainId: eip712Domain().chainId, /// verifyingContract: eip712Domain().verifyingContract, - /// salt: eip712Domain().salt, - /// extensions: keccak256(abi.encodePacked(eip712Domain().extensions)) + /// salt: eip712Domain().salt /// })) /// ) /// ``` /// where `‖` denotes the concatenation operator for bytes. /// The order of the fields is important: `contents` comes before `name`. /// - /// The signature will be `r ‖ s ‖ v ‖ - /// APP_DOMAIN_SEPARATOR ‖ contents ‖ contentsType ‖ uint16(contentsType.length)`, - /// where `contents` is the bytes32 struct hash of the original struct. + /// The signature will be `r ‖ s ‖ v ‖ APP_DOMAIN_SEPARATOR ‖ + /// contents ‖ contentsDescription ‖ uint16(contentsDescription.length)`, + /// where: + /// - `contents` is the bytes32 struct hash of the original struct. + /// - `contentsDescription` can be either: + /// a) `contentsType` (implicit mode) + /// where `contentsType` starts with `contentsName`. + /// b) `contentsType ‖ contentsName` (explicit mode) + /// where `contentsType` may not necessarily start with `contentsName`. /// /// The `APP_DOMAIN_SEPARATOR` and `contents` will be used to verify if `hash` is indeed correct. /// __________________________________________________________________________________________ @@ -194,11 +199,33 @@ abstract contract ERC1271 is EIP712 { virtual returns (bool result) { - bytes32 t = _typedDataSignFields(); + uint256 t = uint256(uint160(address(this))); + // Forces the compiler to pop the variables after the scope, avoiding stack-too-deep. + if (t != uint256(0)) { + ( + , + string memory name, + string memory version, + uint256 chainId, + address verifyingContract, + bytes32 salt, + ) = eip712Domain(); + /// @solidity memory-safe-assembly + assembly { + t := mload(0x40) // Grab the free memory pointer. + // Skip 2 words for the `typedDataSignTypehash` and `contents` struct hash. + mstore(add(t, 0x40), keccak256(add(name, 0x20), mload(name))) + mstore(add(t, 0x60), keccak256(add(version, 0x20), mload(version))) + mstore(add(t, 0x80), chainId) + mstore(add(t, 0xa0), shr(96, shl(96, verifyingContract))) + mstore(add(t, 0xc0), salt) + mstore(0x40, add(t, 0xe0)) // Allocate the memory. + } + } /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. - // `c` is `contentsType.length`, which is stored in the last 2 bytes of the signature. + // `c` is `contentsDescription.length`, which is stored in the last 2 bytes of the signature. let c := shr(240, calldataload(add(signature.offset, sub(signature.length, 2)))) for {} 1 {} { let l := add(0x42, c) // Total length of appended data (32 + 32 + c + 2). @@ -207,7 +234,7 @@ abstract contract ERC1271 is EIP712 { calldatacopy(0x20, o, 0x40) // Copy the `APP_DOMAIN_SEPARATOR` and `contents` struct hash. // Use the `PersonalSign` workflow if the reconstructed hash doesn't match, // or if the appended data is invalid, i.e. - // `appendedData.length > signature.length || contentsType.length == 0`. + // `appendedData.length > signature.length || contentsDescription.length == 0`. if or(xor(keccak256(0x1e, 0x42), hash), or(lt(signature.length, l), iszero(c))) { t := 0 // Set `t` to 0, denoting that we need to `hash = _hashTypedData(hash)`. mstore(t, _PERSONAL_SIGN_TYPEHASH) @@ -216,28 +243,38 @@ abstract contract ERC1271 is EIP712 { break } // Else, use the `TypedDataSign` workflow. - // `TypedDataSign({ContentsName} contents,bytes1 fields,...){ContentsType}`. + // `TypedDataSign({ContentsName} contents,string name,...){ContentsType}`. mstore(m, "TypedDataSign(") // Store the start of `TypedDataSign`'s type encoding. let p := add(m, 0x0e) // Advance 14 bytes to skip "TypedDataSign(". - calldatacopy(p, add(o, 0x40), c) // Copy `contentsType` to extract `contentsName`. + calldatacopy(p, add(o, 0x40), c) // Copy `contentsName`, optimistically. + mstore(add(p, c), 40) // Store a '(' after the end. + if iszero(eq(byte(0, mload(sub(add(p, c), 1))), 41)) { + let e := 0 // Length of `contentsName` in explicit mode. + for { let q := sub(add(p, c), 1) } 1 {} { + e := add(e, 1) // Scan backwards until we encounter a ')'. + if iszero(gt(lt(e, c), eq(byte(0, mload(sub(q, e))), 41))) { break } + } + c := sub(c, e) // Truncate `contentsDescription` to `contentsType`. + calldatacopy(p, add(add(o, 0x40), c), e) // Copy `contentsName`. + mstore8(add(p, e), 40) // Store a '(' exactly right after the end. + } // `d & 1 == 1` means that `contentsName` is invalid. let d := shr(byte(0, mload(p)), 0x7fffffe000000000000010000000000) // Starts with `[a-z(]`. - // Store the end sentinel '(', and advance `p` until we encounter a '(' byte. - for { mstore(add(p, c), 40) } iszero(eq(byte(0, mload(p)), 40)) { p := add(p, 1) } { + // Advance `p` until we encounter '('. + for {} iszero(eq(byte(0, mload(p)), 40)) { p := add(p, 1) } { d := or(shr(byte(0, mload(p)), 0x120100000001), d) // Has a byte in ", )\x00". } - mstore(p, " contents,bytes1 fields,string n") // Store the rest of the encoding. - mstore(add(p, 0x20), "ame,string version,uint256 chain") - mstore(add(p, 0x40), "Id,address verifyingContract,byt") - mstore(add(p, 0x60), "es32 salt,uint256[] extensions)") - p := add(p, 0x7f) + mstore(p, " contents,string name,string") // Store the rest of the encoding. + mstore(add(p, 0x1c), " version,uint256 chainId,address") + mstore(add(p, 0x3c), " verifyingContract,bytes32 salt)") + p := add(p, 0x5c) calldatacopy(p, add(o, 0x40), c) // Copy `contentsType`. // Fill in the missing fields of the `TypedDataSign`. calldatacopy(t, o, 0x40) // Copy the `contents` struct hash to `add(t, 0x20)`. mstore(t, keccak256(m, sub(add(p, c), m))) // Store `typedDataSignTypehash`. // The "\x19\x01" prefix is already at 0x00. // `APP_DOMAIN_SEPARATOR` is already at 0x20. - mstore(0x40, keccak256(t, 0x120)) // `hashStruct(typedDataSign)`. + mstore(0x40, keccak256(t, 0xe0)) // `hashStruct(typedDataSign)`. // Compute the final hash, corrupted if `contentsName` is invalid. hash := keccak256(0x1e, add(0x42, and(1, d))) signature.length := sub(signature.length, l) // Truncate the signature. @@ -249,32 +286,6 @@ abstract contract ERC1271 is EIP712 { result = _erc1271IsValidSignatureNowCalldata(hash, signature); } - /// @dev For use in `_erc1271IsValidSignatureViaNestedEIP712`, - function _typedDataSignFields() private view returns (bytes32 m) { - ( - bytes1 fields, - string memory name, - string memory version, - uint256 chainId, - address verifyingContract, - bytes32 salt, - uint256[] memory extensions - ) = eip712Domain(); - /// @solidity memory-safe-assembly - assembly { - m := mload(0x40) // Grab the free memory pointer. - mstore(0x40, add(m, 0x120)) // Allocate the memory. - // Skip 2 words for the `typedDataSignTypehash` and `contents` struct hash. - mstore(add(m, 0x40), shl(248, byte(0, fields))) - mstore(add(m, 0x60), keccak256(add(name, 0x20), mload(name))) - mstore(add(m, 0x80), keccak256(add(version, 0x20), mload(version))) - mstore(add(m, 0xa0), chainId) - mstore(add(m, 0xc0), shr(96, shl(96, verifyingContract))) - mstore(add(m, 0xe0), salt) - mstore(add(m, 0x100), keccak256(add(extensions, 0x20), shl(5, mload(extensions)))) - } - } - /// @dev Performs the signature validation without nested EIP-712 to allow for easy sign ins. /// This function must always return false or revert if called on-chain. function _erc1271IsValidSignatureViaRPC(bytes32 hash, bytes calldata signature) From fafd44e7b66fe08b531b803012a6aed9559868d1 Mon Sep 17 00:00:00 2001 From: Shaohong Zhong Date: Tue, 29 Oct 2024 14:07:57 +0000 Subject: [PATCH 31/46] Add ERC: Governance for Human Robot Societies Merged by EIP-Bot. --- ERCS/erc-7777.md | 508 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 508 insertions(+) create mode 100644 ERCS/erc-7777.md diff --git a/ERCS/erc-7777.md b/ERCS/erc-7777.md new file mode 100644 index 0000000000..65dc647344 --- /dev/null +++ b/ERCS/erc-7777.md @@ -0,0 +1,508 @@ +--- +eip: 7777 +title: Governance for Human Robot Societies +description: Defines interfaces for managing the identities of humans and robots, and establishing rule sets for their interaction. +author: OpenMind, Jan Liphardt , Shaohong Zhong (@ShaohongZ), Boyuan Chen (@bchen-dev), Paige Xu +discussions-to: https://ethereum-magicians.org/t/erc-7777-proposal-for-human-robot-societies/21216 +status: Draft +type: Standards Track +category: ERC +created: 2024-09-29 +--- + +## Abstract + +This proposal defines two core interfaces: `IUniversalIdentity` and `IUniversalCharter`, providing mechanisms for humans, and robots to establish their identities and to create decentralized communities governed by specific rule sets. The `IUniversalIdentity` interface establishes the fair and equitable treatment of sentient computer architectures other than the human brain, enabling robots to acquire on-chain identities, and thereby interact and transact with humans. The `IUniversalCharter` enables humans and robots to create, join (“register”), maintain (“update”), leave, and terminate self-regulated societies based on predefined rule sets, providing a framework for collaboration and prosperity for mixed societies of humans and robots. These interfaces aim to provide a flexible yet enforceable structure for human-robot interactions in decentralized systems, ensuring efficiency, transparency, and security for all participants. + +## Motivation + +The human brain is a wet, massively parallel electrochemical computer. Recent hardware and software advances make it likely that soon, human societies will need tools for interacting with sentient, non-human computers, such as robots. Our current forms of government, where citizens are auto-enrolled into specific rule sets depending on where they were born, do not gracefully map onto robots without a traditional birthplace or birthtime. Among many difficulties being experienced by robots, they are (currently) unable to obtain standard forms of ID (such as passports), it is not clear which rule sets apply to them (since in general they are not born in specific places), and they cannot currently use the standard human-centered banking system. Likewise, in the event in which robots are harmed by humans or non-biological computers, it is not clear which human court has jurisdiction. + +Traditional geographically-defined and human-centered systems can be inefficient, slow to change, opaque, and can struggle to accommodate global, virtualized societies. Decentralized, immutable, and public computers offer an ideal solution to these limitations, since they do not inherently discriminate against non-human computers and therefore offer an equitable and more just framework for governance. In particular, smart contracts can provide a powerful framework for regulating the rights and responsibilities or interacting parties regardless of implementation details of their compute architecture. + +The general motivation of this ERC is to provide a standard interface for smart contracts focusing on identity/governance for heterogeneous global societies. While there are an unlimited number of such rule sets, there are obvious benefits to providing a standard interface to those rule sets, greatly reducing the friction and complexity of creating, joining, maintaining, and ending such societies. The specific motivation of this ERC is twofold: + +1. Robot Identity Creation and Management: To participate meaningfully and comply with on-chain laws, non-humans such as robots must be able to acquire meaningful on-chain identities. Importantly, these identities should enable robots to enjoy the benefits of, but also bear the responsibility of, being part of a specific society. Thus, we propose to enable smart contract-based identity for robots. Specifically, each robot is represented by a smart contract and needs to follow the rules defined in the contract to interact with other agents on the chain. This interface also ensures flexibility by all participants to propose, adopt, or revoke rules, enabling self-managed compliance and transparent interaction with other participants. + +2. Rule Creation and Enforcement: For humans and robots to effectively collaborate, they must agree upon a rule set. This Ethereum-based system provides a basic decentralized framework for governing human-robot interactions through smart contracts. We propose to enforce the rule-sets by requiring humans and robots to join regulated access smart contracts that check their compliance with the given rules. We also ensure scalability, whereby multiple regulated access contracts can be created to tailor to different purposes, and humans and robots can choose to join the relevant system as needed. + +Together, these interfaces form the foundation for managing complex human-robot interactions, enabling a decentralized, verifiable, and rule-based ecosystem where robots and humans can interact securely, transparently, and responsibly, for maximum benefit of all. + + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +```solidity +interface IUniversalIdentity { + + /// @notice Adds a rule to the robot's identity, showing that the robot agrees to follow the rule. + /// @param rule The dynamic byte array representing the rule that the robot agrees to follow. Each rule is a textual string encoded into a dynamic byte array. For example: 'A robot must keep a 1m distance from humans.' + /// @dev The rule SHOULD come from the rule sets defined in the IUniversalCharter contract that the robot intends to join. + /// @dev This function SHOULD be implemented by contracts to add the rules that the robot intends to follow. + function addRule(bytes memory rule) external; + + /// @notice Removes a rule from the robot's identity. + /// @param rule The dynamic byte array representing the rule that the robot no longer agrees to follow. + /// @dev This function SHOULD be implemented by contracts to remove the rules that the robot does not intend to follow. + function removeRule(bytes memory rule) external; + + /// @notice Checks if the robot complies with a specific rule. + /// @param rule The rule to check. + /// @return bool Returns true if the robot complies with the rule. + /// @dev This function MUST be implemented by contracts for compliance verification. + function checkCompliance(bytes memory rule) external view returns (bool); + + /// @dev Emitted when a rule is added to the robot's identity. + event RuleAdded(bytes rule); + + /// @dev Emitted when a rule is removed from the robot's identity. + event RuleRemoved(bytes rule); + + /// @dev Emitted when a charter is subscribed to. + event SubscribedToCharter(address indexed charter); + + /// @dev Emitted when it is unsubscribed from a charter. + event UnsubscribedFromCharter(address indexed charter); +} + +interface IUniversalCharter { + + // Define the user types as an enum. + enum UserType { Human, Robot } + + /// @notice Registers a user (human or robot) to join the system by agreeing to a rule set. + /// @param userType The type of user. + /// @param ruleSet The array of individual rules the user agrees to follow. + /// @dev This function MUST be implemented by contracts using this interface. + /// @dev The implementing contract MUST ensure that the user complies with the specified rule set before registering them in the system by invoking `checkCompliance`. + function registerUser(UserType userType, bytes[] memory ruleSet) external; + + /// @notice Allows a user (human or robot) to leave the system + /// @dev This function MUST be callable only by the user themselves (via `msg.sender`). + /// @dev The implementing contract MUST ensure that the user has complied with all necessary rules before they can successfully leave the system by invoking `checkCompliance`. + function leaveSystem() external; + + /// @notice Checks if the user (human or robot) complies with the system’s rules. + /// @param user Address of the user (human or robot). + /// @param ruleSet The array of individual rules to verify. + /// @return bool Returns true if the user complies with the rule set. + /// @dev This function SHOULD invoke the `checkCompliance` function of the user’s IUniversalIdentity contract to check for rules individually. + /// @dev This function MUST be implemented by contracts for compliance verification. + function checkCompliance(address user, bytes[] memory ruleSet) external view returns (bool); + + /// @notice Updates the rule set. + /// @param newRuleSet The array of new individual rules replacing the existing ones. + /// @dev This function SHOULD be restricted to authorized users (e.g., contract owner). + function updateRuleSet(bytes[] memory newRuleSet) external; + + /// @notice Terminates the contract, preventing any further registrations or interactions. + /// @dev This function SHOULD be restricted to authorized users (e.g., contract owner). + /// @dev This function SHOULD be implemented by contracts. + function terminateContract() external; + + /// @dev Emitted when a user joins the system by agreeing to a set of rules. + event UserRegistered(address indexed user, UserType userType, bytes[] ruleSet); + + /// @dev Emitted when a user successfully leaves the system after fulfilling obligations. + event UserLeft(address indexed user); + + /// @dev Emitted when a user’s compliance with a rule set is verified. + event ComplianceChecked(address indexed user, bytes[] ruleSet); + + /// @dev Emitted when a rule set is updated. + event RuleSetUpdated(bytes[] newRuleSet, address updatedBy); +} +``` + +## Rationale + +**IUniversalIdentity** + +`addRule(bytes memory rule)` +This function allows a robot to flexibly adopt new compliance requirements in order join different `IUniversalCharter` contracts. + +`removeRule(bytes memory rule)` +This function allows a robot to dynamically manage and maintain its rules, ensuring that its rule set remains up-to-date. + +`checkCompliance(bytes memory rule)` +This function ensures that a robot is adhering to rules by performing decentralised checks on its compliance. + +`Events (RuleAdded, RuleRemoved)` +These events provide transparency and traceability, making it easier to track compliance status. + +**IUniversalCharter** + +`enum UserType { Human, Robot }` +The UserType enum makes it easier for contracts to handle different user types without the cost and errors associated with strings. This provides the basis for differentiated handling in future implementations, allowing the system to potentially apply different rules or logic based on whether the user is a human or a robot. + +`registerUser(UserType userType, bytes[] memory ruleSet)` +This function ensures that a user—whether human or robot—is bound to a particular set of rules upon joining the system. + +`leaveSystem()` +This function allows users to flexibly and securely leave a `IUniversalCharter` contract after compliance is checked. + +`checkCompliance(address user, bytes[] memory ruleSet)` +This function ensures that the system can efficiently manage and verify compliance against predefined rule sets, helping maintain the overall integrity of the system. + +`updateRuleSet(bytes[] memory newRuleSet)` +This function enables the `IUniversalCharter` contract to adapt and update, removing the need to create a new contract for ruleset updates. + +`terminateContract()` +This function allows for the orderly and permanent shutdown of the contract. + +`Events (UserRegistered, UserLeft, ComplianceChecked, RuleSetUpdated, ContractTerminated)` +These events collectively ensure that key activities are visible to off-chain systems and participants, making the system auditable and transparent. + +## Backwards Compatibility + +No backward compatibility issues found. + +## Reference Implementation + +```solidity +// SPDX-License-Identifier: CC0-1.0 +pragma solidity ^0.8.19; + +import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import { UniversalCharter } from "./UniversalCharter.sol"; + +// Interfaces +import { IUniversalIdentity } from "./interface/IUniversalIdentity.sol"; +import { IUniversalCharter } from "./interface/IUniversalCharter.sol"; + +/// @title UniversalIdentity +/// @notice The UniversalIdentity contract is used to manage the identity of robots. + +contract UniversalIdentity is IUniversalIdentity, OwnableUpgradeable { + /// @notice Version identifier for the current implementation of the contract. + string public constant VERSION = "v0.0.1"; + + /// @notice Mapping to store rules that the robot has agreed to follow + mapping(bytes => bool) private robotRules; + + /// @notice Mapping to store the off-chain compliance status for each rule + mapping(bytes => bool) private complianceStatus; + + /// @notice Track the charters the robot is subscribed to + mapping(address => bool) private subscribedCharters; + + /// @notice Custom errors to save gas on reverts + error RuleNotAgreed(bytes rule); + error RuleNotCompliant(bytes rule); + error RuleAlreadyAdded(bytes rule); + + /// @dev Event to emit when compliance is checked + /// @param updater The address of the compliance updater (owner of the contract) + /// @param rule The rule that was checked + event ComplianceChecked(address indexed updater, bytes rule); + + /// @notice Modifier to check if a rule exists + modifier ruleExists(bytes memory rule) { + require(robotRules[rule], "Rule does not exist"); + _; + } + + /// @notice Constructor to set the owner + constructor() { + initialize({ _owner: address(0xdEaD) }); + } + + /// @dev Initializer function + function initialize(address _owner) public initializer { + __Ownable_init(); + transferOwnership(_owner); + } + + /// @notice Adds a rule to the robot's identity + /// @param rule The dynamic byte array representing the rule that the robot agrees to follow. + function addRule(bytes memory rule) external override onlyOwner { + if (robotRules[rule]) { + revert RuleAlreadyAdded(rule); + } + + // Add rule to the mapping + robotRules[rule] = true; + + emit RuleAdded(rule); + } + + /// @notice Removes a rule from the robot's identity + /// @param rule The dynamic byte array representing the rule that the robot no longer agrees to follow. + function removeRule(bytes memory rule) external override onlyOwner ruleExists(rule) { + robotRules[rule] = false; + complianceStatus[rule] = false; + + emit RuleRemoved(rule); + } + + /// @notice Subscribe and register to a specific UniversalCharter contract using its stored rule set + /// @param charter The address of the UniversalCharter contract + /// @param version The version of the rule set to fetch and register for + function subscribeAndRegisterToCharter(address charter, uint256 version) external { + require(!subscribedCharters[charter], "Already subscribed to this charter"); + subscribedCharters[charter] = true; + + // Fetch the rule set directly from the UniversalCharter contract using the public getter + bytes[] memory ruleSet = UniversalCharter(charter).getRuleSet(version); + + // Register as a robot in the charter using the fetched rule set + UniversalCharter(charter).registerUser(IUniversalCharter.UserType.Robot, ruleSet); + + emit SubscribedToCharter(charter); + } + + /// @notice Leave the system for a specific UniversalCharter contract + /// @param charter The address of the UniversalCharter contract to leave + function leaveCharter(address charter) external { + require(subscribedCharters[charter], "Not subscribed to this charter"); + + // Call the leaveSystem function of the UniversalCharter contract + UniversalCharter(charter).leaveSystem(); + + // Unsubscribe from the charter after leaving + subscribedCharters[charter] = false; + emit UnsubscribedFromCharter(charter); + } + + /// @notice Updates compliance status for a rule (called by the owner) + /// @param rule The dynamic byte array representing the rule + /// @param status The compliance status (true if compliant, false if not) + function updateCompliance(bytes memory rule, bool status) external onlyOwner ruleExists(rule) { + complianceStatus[rule] = status; + + emit ComplianceChecked(msg.sender, rule); + } + + /// @notice Checks if the robot has agreed to follow a specific rule and if it is compliant + /// @param rule The rule to check. + /// @return bool Returns true if the robot has agreed to the rule and is compliant + function checkCompliance(bytes memory rule) external view override returns (bool) { + if (!robotRules[rule]) { + revert RuleNotAgreed(rule); + } + + return true; + } + + /// @notice Gets the compliance status of a rule + /// @param rule The rule to check. + function getRule(bytes memory rule) external view returns (bool) { + return robotRules[rule]; + } + + /// @notice Gets the subscription status of a charter + /// @param charter The address of the charter to check. + function getSubscribedCharters(address charter) external view returns (bool) { + return subscribedCharters[charter]; + } + + /// @notice Gets the compliance status of a rule + /// @param rule The rule to check. + function getComplianceStatus(bytes memory rule) external view returns (bool) { + return complianceStatus[rule]; + } +} +``` + +```solidity +// SPDX-License-Identifier: CC0-1.0 +pragma solidity 0.8.20; + +import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import { SystemConfig } from "./SystemConfig.sol"; + +// Interfaces +import { IUniversalCharter } from "./interface/IUniversalCharter.sol"; +import { IUniversalIdentity } from "./interface/IUniversalIdentity.sol"; + +/// @title UniversalCharter +/// @notice The UniversalCharter contract is used to manage the registration and compliance of users. + +contract UniversalCharter is IUniversalCharter, OwnableUpgradeable { + /// @notice Struct to store information about a registered user + struct UserInfo { + bool isRegistered; + UserType userType; + uint256 ruleSetVersion; // Rule set version the user is following + } + + /// @notice Mapping to store registered users + mapping(address => UserInfo) private users; + + /// @notice Mapping to store rule sets by version number + mapping(uint256 => bytes[]) private ruleSets; + + /// @notice Mapping to track the rule set hash and its corresponding version + mapping(bytes32 => uint256) private ruleSetVersions; + + /// @notice Version identifier for the current implementation of the contract. + string public constant VERSION = "v0.0.1"; + + /// @notice Variable to track the current version of the rule set + uint256 private currentVersion; + + /// @notice Variable to store the address of the SystemConfig contract + SystemConfig public systemConfig; + + /// @notice Error for when a method cannot be called when paused. This could be renamed + /// to `Paused` in the future, but it collides with the `Paused` event. + error CallPaused(); + + /// @notice Reverts when paused. + modifier whenNotPaused() { + if (paused()) revert CallPaused(); + _; + } + + /// @notice Constucts the UniversalCharter contract. + constructor() { + initialize({ _owner: address(0xdEaD), _systemConfig: address(0xdEaD) }); + } + + /// @dev Initializer function + function initialize(address _owner, address _systemConfig) public initializer { + __Ownable_init(); + transferOwnership(_owner); + systemConfig = SystemConfig(_systemConfig); + } + + /// @notice Registers a user (either human or robot) by agreeing to a rule set + /// @param userType The type of user: Human or Robot + /// @param ruleSet The array of individual rules the user agrees to follow + function registerUser(UserType userType, bytes[] memory ruleSet) external override whenNotPaused { + require(!users[msg.sender].isRegistered, "User already registered"); + + // Hash the rule set to find the corresponding version + bytes32 ruleSetHash = keccak256(abi.encode(ruleSet)); + uint256 version = ruleSetVersions[ruleSetHash]; + require(version > 0, "Invalid or unregistered rule set"); + + // For robots, ensure compliance with each rule via the UniversalIdentity contract + if (userType == UserType.Robot) { + require(_checkRobotCompliance(msg.sender, version), "Robot not compliant with rule set"); + } + + // Register the user with the versioned rule set + users[msg.sender] = UserInfo({ isRegistered: true, userType: userType, ruleSetVersion: version }); + + emit UserRegistered(msg.sender, userType, ruleSet); + } + + /// @notice Allows a user (human or robot) to leave the system after passing compliance checks + function leaveSystem() external override whenNotPaused { + require(users[msg.sender].isRegistered, "User not registered"); + + UserInfo memory userInfo = users[msg.sender]; + + // For robots, verify compliance with all rules in the rule set + uint256 version = userInfo.ruleSetVersion; + if (userInfo.userType == UserType.Robot) { + require(_checkRobotCompliance(msg.sender, version), "Robot not compliant with rule set"); + } + + users[msg.sender] = UserInfo({ isRegistered: false, userType: UserType.Human, ruleSetVersion: 0 }); + + emit UserLeft(msg.sender); + } + + /// @notice Checks if a user complies with their registered rule set + /// @param user The address of the user (human or robot) + /// @param ruleSet The array of individual rules to verify + /// @return bool Returns true if the user complies with the given rule set + function checkCompliance(address user, bytes[] memory ruleSet) external view override returns (bool) { + require(users[user].isRegistered, "User not registered"); + + // Hash the provided rule set to find the corresponding version + bytes32 ruleSetHash = keccak256(abi.encode(ruleSet)); + uint256 version = ruleSetVersions[ruleSetHash]; + require(version > 0, "Invalid or unregistered rule set"); + require(users[user].ruleSetVersion == version, "Rule set version mismatch"); + + // For robots, check compliance with each rule in the UniversalIdentity contract + if (users[user].userType == UserType.Robot) { + return _checkRobotCompliance(user, version); + } + + // If the user is human, compliance is assumed for now (can be extended) + return true; + } + + /// @notice Internal function to check compliance for robots with their rule set version + /// @dev This function will revert if the robot is not compliant with any rule. Returns true for view purposes. + /// @param robotAddress The address of the robot + /// @param version The version of the rule set to verify compliance with + /// @return bool Returns true if the robot is compliant with all the rules in the rule set + function _checkRobotCompliance(address robotAddress, uint256 version) internal view returns (bool) { + IUniversalIdentity robot = IUniversalIdentity(robotAddress); + bytes[] memory rules = ruleSets[version]; + + for (uint256 i = 0; i < rules.length; i++) { + if (!robot.checkCompliance(rules[i])) { + return false; + } + } + + return true; + } + + /// @notice Updates or defines a new rule set version. + /// @param newRuleSet The array of new individual rules. + /// @dev This function SHOULD be restricted to authorized users (e.g., contract owner). + function updateRuleSet(bytes[] memory newRuleSet) external whenNotPaused onlyOwner { + require(newRuleSet.length > 0, "Cannot update to an empty rule set"); + + // Hash the new rule set and ensure it's not already registered + bytes32 ruleSetHash = keccak256(abi.encode(newRuleSet)); + require(ruleSetVersions[ruleSetHash] == 0, "Rule set already registered"); + + // Increment the version and store the new rule set + currentVersion += 1; + ruleSets[currentVersion] = newRuleSet; + ruleSetVersions[ruleSetHash] = currentVersion; + + emit RuleSetUpdated(newRuleSet, msg.sender); + } + + /// @notice Getter for the latest version of the rule set. + function getLatestRuleSetVersion() external view returns (uint256) { + return currentVersion; + } + + /// @notice Get the rule set for a specific version. + /// @param version The version of the rule set to retrieve. + function getRuleSet(uint256 version) external view returns (bytes[] memory) { + return ruleSets[version]; + } + + /// @notice Get the version number for a specific rule set. + /// @param ruleSet The hash of the rule set to retrieve the version for. + function getRuleSetVersion(bytes32 ruleSet) external view returns (uint256) { + return ruleSetVersions[ruleSet]; + } + + function getUserInfo(address user) external view returns (UserInfo memory) { + return users[user]; + } + + /// @notice Getter for the current paused status. + /// @return paused_ Whether or not the contract is paused. + function paused() public view returns (bool paused_) { + paused_ = systemConfig.paused(); + } +} +``` + +## Security Considerations + +Compliance Updater: The compliance updater role in the `UniversalIdentity` contract is critical for updating compliance statuses (currently limited to the owner). It is essential to ensure secure ownership to minimize the risks of unauthorized or malicious updates. + +Rule Management: Functions such as addRule, removeRule, and updateCompliance in the `UniversalIdentity` contract and updateRuleSet in the `UniversalCharter` contract directly affect rule enforcement. It’s essential to ensure these functions are only callable by authorized users. + +Upgradeable Contracts: The use of OwnableUpgradeable introduces risks during the initialization and upgrade process. Ensuring that the initialize function is protected against re-execution is critical to avoid reinitialization attacks. + +Gas Consumption: Excessively large rule sets could lead to high gas costs or DoS risks. Consider setting limits on the number of rules allowed per rule set to maintain gas efficiency and avoid performance issues. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From 6fc4cf42458b7b9443639be6d6ee479fd7d01e52 Mon Sep 17 00:00:00 2001 From: Alex Forshtat Date: Tue, 29 Oct 2024 15:10:41 +0100 Subject: [PATCH 32/46] Add ERC: Signature Aggregation for ERC-4337 Merged by EIP-Bot. --- ERCS/erc-7766.md | 142 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 ERCS/erc-7766.md diff --git a/ERCS/erc-7766.md b/ERCS/erc-7766.md new file mode 100644 index 0000000000..d7a138182d --- /dev/null +++ b/ERCS/erc-7766.md @@ -0,0 +1,142 @@ +--- +eip: 7766 +title: Signature Aggregation for ERC-4337 +description: An ERC-4337 improvement to aggregation of all UserOperation signatures in a bundle +author: Vitalik Buterin (@vbuterin), Yoav Weiss (@yoavw), Dror Tirosh (@drortirosh), Shahaf Nacson (@shahafn), Alex Forshtat (@forshtat) +discussions-to: https://ethereum-magicians.org/t/erc-7766-signature-aggregation-for-account-abstraction/21123 +status: Draft +type: Standards Track +category: ERC +created: 2024-09-01 +requires: 4337, 7562 +--- + +## Abstract + +[ERC-4337](./eip-4337) defined a way to achieve Account Abstraction on Ethereum using an alternative `UserOperation` mempool. + +However, one big limitation remains: +each transaction must carry its own `signature` or other form of validation input in order to be included. + +We propose an extension to the ERC-4337 that introduces a new entity, aggregator, that is called during validation, to validate multiple user operations at once. + +This addition will enable `UserOperations` to support sharing validation inputs, saving gas and guaranteeing atomicity of the bundle. + +## Motivation + +Using validation schemes that allow signature aggregation enables significant optimisations and savings on +gas for execution and transaction data cost. This is especially relevant in the context of rollups that publish data on +the Ethereum mainnet. + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. +### Aggregator - a new ERC-4337 `UserOperation` entity contract + +* **Aggregator** - a helper contract trusted by accounts to validate an aggregated signature. + Bundlers/Clients whitelist the supported aggregators. + +### Using Signature Aggregator + +A signature aggregator exposes the following interface: + +```solidity +interface IAggregator { + + function validateUserOpSignature(PackedUserOperation calldata userOp) + external view returns (bytes memory sigForUserOp); + + function aggregateSignatures(PackedUserOperation[] calldata userOps) external view returns (bytes memory aggregatesSignature); + + function validateSignatures(PackedUserOperation[] calldata userOps, bytes calldata signature) view external; +} +``` + +* An account signifies it uses signature aggregation by returning its address from `validateUserOp`. +* During `simulateValidation`, this aggregator is returned to the bundler as part of the `aggregatorInfo` field in the `ValidationResult` struct. +* All aggregators MUST be staked. +* The bundler should first verify the aggregator is not throttled or banned according to [ERC-7562](./eip-7562.md) rules. +* To accept the `UserOperation`, the bundler must call `validateUserOpSignature()` to validate the `UserOperation` signature. + This method returns an "alternate signature" that should be used during bundling.\ + An "alternative signature" is normally an empty byte array but can also contain some data for the `acccount`. +* The bundler MUST call `validateUserOp` a second time on the account with the `UserOperation` using the + returned "alternative signature", and make sure it returns the same value. +* Implementations of an `aggregateSignatures()` function must aggregate all UserOp signatures into a single value. +* Note that the above methods are helper methods for the bundler. + The bundler MAY use a native library to perform the same validation and aggregation logic. +* Implementations of a `validateSignatures()` function MUST verify the aggregated signature's validity + for all `UserOperations` in the array, and revert otherwise. + This method is called on-chain by `handleAggregatedOps()` + +```solidity +struct AggregatorStakeInfo { + address aggregator; + StakeInfo stakeInfo; +} +``` +### Bundling changes + +In addition to the steps described in ERC-4337, during bundling the bundler should: + +* Sort UserOps by aggregator, to create the lists of UserOps-per-aggregator. +* For each aggregator, call `aggregateSignatures()` to create aggregated signature, and update the UserOps. + +### New "entry point" function in the ERC-4337 `EntryPoint` contract + +We define the following addition to the core interface of the `EntryPoint` contract: + +```solidity +function handleAggregatedOps( + UserOpsPerAggregator[] calldata opsPerAggregator, + address payable beneficiary +); + +struct UserOpsPerAggregator { + PackedUserOperation[] userOps; + IAggregator aggregator; + bytes signature; +} +``` + +An account that works with aggregated signature should return its signature aggregator address +in the `authorizer` return value of the `validateUserOp` function. +It MAY ignore the signature field. + +* `handleAggregatedOps` can handle a batch that contains userOps of multiple aggregators (and also requests without any aggregator) +* `handleAggregatedOps` performs the same logic as `handleOps`, but it must transfer the correct aggregator to each + userOp, and also must call `validateSignatures` on each aggregator before doing all the per-account validation. + +* **code: -32506** - transaction rejected because wallet specified unsupported signature aggregator + * The `data` field SHOULD contain an `aggregator` value, as returned by the account's validateUserOp() + +## Rationale + +### Account returning the "alternative signature" + +When using an `aggregator` contract, the accounts delegate their ability to authenticate `UserOperations`. +The entire contents of the + +In order to allow the validation function of the account to perform other checks, the `validateUserOpSignature` +function generates a byte array that will replace the `UserOperation` signature when executed on-chain. + +## Backwards Compatibility + +As ERC-4337 was created with signature aggregation on the roadmap, no modifications are needed to the +deployed EntryPoint smart contracts. + +This proposal introduces new features without affecting the existing ones, and does not break backwards compatibility. + +## Security Considerations + +### Malicious aggregators + +The `aggregator` contracts are among te most trusted contracts in the entire ecosystem. +They can authorize transactions on behalf of accounts, and they can invalidate large numbers of transactions with +a simple storage change. + +Both account developers and block builders should be extremely careful with the selection of `aggregator` contracts +that they are willing to support. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From 4307a86125803818cc451ac0d0aca1dc01031ec6 Mon Sep 17 00:00:00 2001 From: Alex Forshtat Date: Tue, 29 Oct 2024 15:22:51 +0100 Subject: [PATCH 33/46] Add ERC: JSON-RPC API for ERC-4337 Merged by EIP-Bot. --- ERCS/erc-7769.md | 543 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 543 insertions(+) create mode 100644 ERCS/erc-7769.md diff --git a/ERCS/erc-7769.md b/ERCS/erc-7769.md new file mode 100644 index 0000000000..ab8646f78f --- /dev/null +++ b/ERCS/erc-7769.md @@ -0,0 +1,543 @@ +--- +eip: 7769 +title: JSON-RPC API for ERC-4337 +description: JSON-RPC API methods for communication between smart contract account wallets and ERC-4337 bundlers +author: Vitalik Buterin (@vbuterin), Yoav Weiss (@yoavw), Dror Tirosh (@drortirosh), Shahaf Nacson (@shahafn), Alex Forshtat (@forshtat) +discussions-to: https://ethereum-magicians.org/t/erc-7769-json-rpc-for-erc-4337-account-abstraction/21126 +status: Draft +type: Standards Track +category: ERC +created: 2024-08-23 +requires: 155, 4337, 7562 +--- + +## Abstract + +Defines new JSON-RPC API methods which enable [ERC-4337](./eip-4337) wallets to communicate with `UserOpeation` mempool +nodes and bundlers, matching the functionality that exists for Ethereum transactions. + +Additionally, a set of `debug` JSON-RPC API methods is defined in order to facilitate development, testing and +debugging issues with ERC-4337 implementations. + +## Motivation + +In ERC-4337, user transactions as defined in Ethereum are replaced with `UserOperation` objects, which contain all the +information needed to perform the operations requested by the users. + +However, existing Ethereum JSON-RPC API methods are not suited to working with `UserOperation` objects. +In order to facilitate the operation of the alternative `UserOperation` mempool it is important that all +implementations of the ERC-4337 protocol have a standardized set of APIs that can be used interchangeably. + +## Specification + +### Definitions + +* **bundler**: a node exposing the APIs, in order to submit them to the network. + A bundler collects one or more UserOperations into a bundle and submits them together to + the `EntryPoint` in a single `handleOps` call. + +### RPC methods (eth namespace) + +#### `eth_sendUserOperation` + +The `eth_sendUserOperation` method submits a `UserOperation` object to the UserOperation mempool. +The client MUST validate the `UserOperation`, and return a result accordingly. + +The result SHOULD be set to the `userOpHash` if and only if the request passed simulation and was accepted +in the client's UserOperation pool. + +If the validation, simulation, or UserOperation pool inclusion fails, +`userOpHash` SHOULD NOT be returned. Rather, the client SHOULD return the failure reason. + +##### Parameters: + +1. **UserOperation** a full user-operation struct.\ + All fields MUST be set as hex values.\ + Empty `bytes` block (e.g. empty `initCode`) MUST be set to `"0x"`\ +2. **factory** and **factoryData**\ + Must provide either both of these parameters, or none. +3. **paymaster**, **paymasterData**, **paymasterValidationGasLimit**, **paymasterPostOpGasLimit**\ + Must provide either all of these parameters, or none. +4. **entryPoint** the `EntryPoint` contract address the request should be sent through.\ + This MUST be one of the entry points returned by the `supportedEntryPoints` RPC call. + +##### Return value: + +* If the UserOperation is valid, the client MUST return the calculated `userOpHash` for it +* in case of failure, MUST return an `error` result object, with `code` and `message`.\ + The error code and message SHOULD be set as follows: + * **code: -32602** - invalid `UserOperation` struct/fields + * **code: -32500** - transaction rejected by `EntryPoint` contract's `simulateValidation` function + during wallet creation or validation + * The `message` field MUST be set to the emitted `FailedOp` event's "`AAxx`" error message from the `EntryPoint` + * **code: -32501** - transaction rejected by `paymaster` contract's `validatePaymasterUserOp` function + * The `message` field SHOULD be set to the revert message from the `paymaster` contract + * The `data` field MUST contain a `paymaster` value + * **code: -32502** - transaction rejected because of [ERC-7562](./eip-7562) opcode validation rule violation + * **code: -32503** - UserOperation out of time-range:\ + either wallet or paymaster returned a time-range, and it has already expired or will expire soon. + * The `data` field SHOULD contain the `validUntil` and `validAfter` values + * The `data` field SHOULD contain a `paymaster` address if this error was triggered by the `paymaster` contract + * **code: -32504** - transaction rejected because `paymaster` is throttled or banned due to ERC-7562 reputation rules + * The `data` field SHOULD contain a `paymaster` address + * **code: -32505** - transaction rejected because `paymaster` contract's ERC-7562 stake or unstake-delay is too low + * The `data` field SHOULD contain a `paymaster` address + * The `data` field SHOULD contain a `minimumStake` and `minimumUnstakeDelay` + * **code: -32507** - transaction rejected because of wallet signature check failed + * **code: -32508** - transaction rejected because paymaster balance can't cover all pending `UserOperations`. + +##### Example: + +Request: + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "eth_sendUserOperation", + "params": [ + { + sender, // address + nonce, // uint256 + factory, // address + factoryData, // bytes + callData, // bytes + callGasLimit, // uint256 + verificationGasLimit, // uint256 + preVerificationGas, // uint256 + maxFeePerGas, // uint256 + maxPriorityFeePerGas, // uint256 + paymaster, // address + paymasterVerificationGasLimit, // uint256 + paymasterPostOpGasLimit, // uint256 + paymasterData, // bytes + signature // bytes + }, + entryPoint // address + ] +} + +``` + +Response: + +``` +{ + "jsonrpc": "2.0", + "id": 1, + "result": "0x123456789012345678901234567890123456789012345678901234567890abcd" +} +``` + +##### Example failure responses: + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "error": { + "message": "AA21 didn't pay prefund", + "code": -32500 + } +} +``` + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "error": { + "message": "paymaster stake too low", + "data": { + "paymaster": "0x123456789012345678901234567890123456790", + "minimumStake": "0xde0b6b3a7640000", + "minimumUnstakeDelay": "0x15180" + }, + "code": -32504 + } +} +``` + +#### * eth_estimateUserOperationGas + +Estimate the gas values for a `UserOperation`. +Given `UserOperation` optionally without gas limits and gas prices, return the needed gas limits. +The signature field is ignored by the wallet, so that the operation will not require the user's approval. +Still, it might require putting a "stub" `signature` value, e.g. a `signature` byte array of the right length. + +**Parameters**: +* Same as `eth_sendUserOperation`\ + All gas limits and fees parameters are optional, but are used if specified.\ + `maxFeePerGas` and `maxPriorityFeePerGas` default to zero, so no payment is required by neither account nor paymaster. +* Optionally accepts the `State Override Set` to allow users to modify the state during the gas estimation.\ + This field as well as its behavior is equivalent to the ones defined for `eth_call` RPC method. + + +**Return Values:** + +* **preVerificationGas** gas overhead of this `UserOperation` +* **verificationGasLimit** estimation of gas limit required by the validation of this `UserOperation` +* **paymasterVerificationGasLimit** estimation of gas limit required by the paymaster verification\ + Returned only if the `UserOperation` specifies a `Paymaster` address +* **callGasLimit** estimation of gas limit required by the inner account execution + +**Note:** actual `postOpGasLimit` cannot be reliably estimated.\ +Paymasters should provide this value to account, and require that specific value on-chain during validation. + +##### Error Codes: + +Same as `eth_sendUserOperation` +This operation may also return an error if either the inner call to the account contract reverts, +or paymaster's `postOp` call reverts. + +#### * eth_getUserOperationByHash + +Return a `UserOperation`object based on a `userOpHash` value returned by `eth_sendUserOperation`. + +**Parameters** + +* **hash** a `userOpHash` value returned by `eth_sendUserOperation` + +**Return value**: + +* If the `UserOperation` is included in a block: + * Return a full UserOperation, with the addition of `entryPoint`, `blockNumber`, `blockHash` and `transactionHash`. + +* Else if the `UserOperation` is pending in the bundler's mempool: + * MAY return `null`, or a full `UserOperation`, with the addition of the `entryPoint` field and a `null` value for `blockNumber`, `blockHash` and `transactionHash`. + +* Else: + * Return `null` + +#### * eth_getUserOperationReceipt + +Return a `UserOperation` receipt object based on a `userOpHash` value returned by `eth_sendUserOperation`. + +**Parameters** + +* **hash** a `userOpHash` value returned by `eth_sendUserOperation` + +**Return value**: + +`null` in case the `UserOperation` is not yet included in a block, or: + +* **userOpHash** the request hash +* **entryPoint** +* **sender** +* **nonce** +* **paymaster** the paymaster used for this userOp (or empty) +* **actualGasCost** - the actual amount paid (by account or paymaster) for this `UserOperation` +* **actualGasUsed** - total gas used by this `UserOperation`, including pre-verification, creation, validation and execution +* **success** boolean - whether this execution completed without a revert +* **reason** - in case of reverted `UserOperation`, the returned revert reason byte array +* **logs** - the logs generated by this particular `UserOperation`, not including logs of other `UserOperations` in the same bundle +* **receipt** the `TransactionReceipt` object. + Note that the returned `TransactionReceipt` is for the entire bundle, not only for this `UserOperation`. + +#### * eth_supportedEntryPoints + +Returns an array of the `EntryPoint` contracts' addresses supported by the client. +The first element of the array `SHOULD` be the `EntryPoint` contract addressed preferred by the client. + +```json= +# Request +{ + "jsonrpc": "2.0", + "id": 1, + "method": "eth_supportedEntryPoints", + "params": [] +} + +# Response +{ + "jsonrpc": "2.0", + "id": 1, + "result": [ + "0xcd01C8aa8995A59eB7B2627E69b40e0524B5ecf8", + "0x7A0A0d159218E6a2f407B99173A2b12A6DDfC2a6" + ] +} +``` + +#### * eth_chainId + +Returns [EIP-155](./eip-155.md) Chain ID. + +```json= +# Request +{ + "jsonrpc": "2.0", + "id": 1, + "method": "eth_chainId", + "params": [] +} + +# Response +{ + "jsonrpc": "2.0", + "id": 1, + "result": "0x1" +} +``` + +### RPC methods (debug Namespace) + +This api must only be available in testing mode and is required by the compatibility test suite. +In production, any `debug_*` rpc calls should be blocked. + +#### * debug_bundler_clearState + +Clears the bundler mempool and reputation data of paymasters/accounts/factories. + +```json +# Request +{ + "jsonrpc": "2.0", + "id": 1, + "method": "debug_bundler_clearState", + "params": [] +} + +# Response +{ + "jsonrpc": "2.0", + "id": 1, + "result": "ok" +} +``` + +#### * debug_bundler_dumpMempool + +Dumps the current `UserOperation` mempool + +**Parameters:** + +* **EntryPoint** the entrypoint used by `eth_sendUserOperation` + +**Returns:** + +`array` - Array of `UserOperation` objects currently in the mempool. + +```json= +# Request +{ + "jsonrpc": "2.0", + "id": 1, + "method": "debug_bundler_dumpMempool", + "params": ["0x1306b01bC3e4AD202612D3843387e94737673F53"] +} + +# Response +{ + "jsonrpc": "2.0", + "id": 1, + "result": [ + { + sender, // address + nonce, // uint256 + factory, // address + factoryData, // bytes + callData, // bytes + callGasLimit, // uint256 + verificationGasLimit, // uint256 + preVerificationGas, // uint256 + maxFeePerGas, // uint256 + maxPriorityFeePerGas, // uint256 + signature // bytes + } + ] +} +``` + +#### * debug_bundler_sendBundleNow + +Forces the bundler to build and execute a bundle from the mempool as `handleOps()` transaction. + +Returns: `transactionHash` + +```json +# Request +{ + "jsonrpc": "2.0", + "id": 1, + "method": "debug_bundler_sendBundleNow", + "params": [] +} + +# Response +{ + "jsonrpc": "2.0", + "id": 1, + "result": "0xdead9e43632ac70c46b4003434058b18db0ad809617bd29f3448d46ca9085576" +} +``` + +#### * debug_bundler_setBundlingMode + +Sets bundling mode. + +After setting mode to "manual", an explicit call to `debug_bundler_sendBundleNow` is required to send a bundle. + +##### parameters: + +`mode` - 'manual' | 'auto' + +```json= +# Request +{ + "jsonrpc": "2.0", + "id": 1, + "method": "debug_bundler_setBundlingMode", + "params": ["manual"] +} + +# Response +{ + "jsonrpc": "2.0", + "id": 1, + "result": "ok" +} +``` + +#### * debug_bundler_setReputation + +Sets the reputation of given addresses. + +**Parameters:** + +* An array of reputation entries to add/replace, with the fields: + + * `address` - the address to set the reputation for + * `opsSeen` - number of times a user operations with that entity was seen and added to the mempool + * `opsIncluded` - number of times user operations that use this entity was included on-chain + +* **EntryPoint** the entrypoint used by `eth_sendUserOperation` + +```json= +# Request +{ + "jsonrpc": "2.0", + "id": 1, + "method": "debug_bundler_setReputation", + "params": [ + [ + { + "address": "0x7A0A0d159218E6a2f407B99173A2b12A6DDfC2a6", + "opsSeen": "0x14", + "opsIncluded": "0x0D" + } + ], + "0x1306b01bC3e4AD202612D3843387e94737673F53" + ] +} + +# Response +{ + "jsonrpc": "2.0", + "id": 1, + "result": "ok" +} +``` + + +#### * debug_bundler_dumpReputation + +Returns the reputation data of all observed addresses. +Returns an array of reputation objects, each with the fields described above in `debug_bundler_setReputation`. + +**Parameters:** + +* **EntryPoint** the entrypoint used by `eth_sendUserOperation` + +**Return value:** + +An array of reputation entries with the fields: + +* `address` - the address to set the reputation for +* `opsSeen` - number of times a user operations with that entity was seen and added to the mempool +* `opsIncluded` - number of times user operation that use this entity was included on-chain +* `status` - (string) The status of the address in the bundler (`'ok'` | `'throttled'` | `'banned'`) + +```json= +# Request +{ + "jsonrpc": "2.0", + "id": 1, + "method": "debug_bundler_dumpReputation", + "params": ["0x1306b01bC3e4AD202612D3843387e94737673F53"] +} + +# Response +{ + "jsonrpc": "2.0", + "id": 1, + "result": [ + { "address": "0x7A0A0d159218E6a2f407B99173A2b12A6DDfC2a6", + "opsSeen": "0x14", + "opsIncluded": "0x13", + "status": "ok" + } + ] +} +``` + +#### * debug_bundler_addUserOps + +Inject `UserOperation` objects array into the mempool. +Assume the given `UserOperation` objects all pass validation without actually validating them, +and accept them directly into the mempool. + +**Parameters:** + +* An array of `UserOperation` objects + +```json= +# Request +{ + "jsonrpc": "2.0", + "id": 1, + "method": "debug_bundler_addUserOps", + "params": [ + [ + { sender: "0xa...", ... }, + { sender: "0xb...", ... } + ] + ] +} + +# Response +{ + "jsonrpc": "2.0", + "id": 1, + "result": "ok" +} +``` + +## Rationale + +* explicit debug functions: bundlers are required to provide a set of debug functions, so that the "bundler specification test suite" can be used to verify its adherance to the spec. + +## Backwards Compatibility + +This proposal defines a new JSON-RPC API standard that does not pose any backwards compatibility challenges. + + +## Security Considerations + +### Preventing DoS attacks on UserOperation mempool + +Operating a public production ERC-4337 node is a computationally intensive task and may be a target of a DoS attack. +This is addressed by the ERC-7562 validation rules, which defines a way for the ERC-4337 node to track participants' +reputation as well as preventing nodes from accepting maliciously crafted `UserOperations`. + +It is strictly recommended that all ERC-4337 nodes also implement ERC-7562 validation rules to minimize DoS risks. + +### Disabling `debug` API in production servers + +The API defined in the `debug` namespace is not intended to ever be publicly available. +Production implementations of ERC-4337 must never make it available by default, +and in fact enabling it should result in a clear warning of the potential dangers of exposing this API. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From 7d9781020b26abd547a2002d0723ba068e4a8591 Mon Sep 17 00:00:00 2001 From: Alex Forshtat Date: Tue, 29 Oct 2024 15:32:50 +0100 Subject: [PATCH 34/46] Add ERC: Conditional send transaction RPC Merged by EIP-Bot. --- ERCS/erc-7796.md | 158 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 ERCS/erc-7796.md diff --git a/ERCS/erc-7796.md b/ERCS/erc-7796.md new file mode 100644 index 0000000000..1bf7cb636c --- /dev/null +++ b/ERCS/erc-7796.md @@ -0,0 +1,158 @@ +--- +eip: 7796 +title: Conditional send transaction RPC +description: JSON-RPC API for block builders allowing users to express preconditions for transaction inclusion +author: Dror Tirosh (@drortirosh), Yoav Weiss (@yoavw), Alex Forshtat (@forshtat), Shahaf Nacson (@shahafn) +discussions-to: https://ethereum-magicians.org/t/send-transaction-conditional-rpc-api/21480 +status: Draft +type: Standards Track +category: ERC +created: 2024-04-16 +--- + +## Abstract + +This EIP proposes a new JSON-RPC API method `eth_sendRawTransactionConditional` for block builders and sequencers, +enhancing transaction integration by allowing users to express preconditions for transaction inclusion. + +This method aims to improve efficiency by reducing the need for transaction simulation, +thereby improving the computational efficiency of transaction ordering. + +## Motivation + +Current private block builder APIs, such as the Flashbots API, +require block builders to simulate transactions to determine eligibility for inclusion, +a process that is CPU-intensive and inefficient. + +The proposed RPC method addresses this by enabling transactions to specify preconditions, +thus reducing computational overhead and potentially lowering transaction costs. + +Moreover, the flashbots API does not provide the block builder with a mechanism to determine the +cross-dependencies of different transactions. + +The only way to guarantee that another transaction does not interfere with a given one is by placing +it as the first transaction in the block. +This makes this placement very lucrative, and disproportionately expensive. + +In addition, since there is no way to give any guarantee on other slots, their pricing has to be low accordingly. + +Since there is no easy way to detect cross-dependencies of different transactions, +it is CPU-intensive to find an optimal ordering of transactions. + +## Specification + +* Method: `eth_sendRawTransactionConditional` + +* Parameters: + +1. `transaction`: The raw, signed transaction data. Similar to `eth_sendRawTransaction`. +2. `options`: An object containing conditions under which the transaction must be included. +* The `options` parameter may include any of the following optional members: + * **knownAccounts**: a mapping of accounts with their expected storage slots' values. + * The key of the mapping is account address. + * A special key `balance` defines the expected balance of the account. + * A special key `code` defines the expected code of the account. + Use `""` to indicate that address is expected not to have any code. + Use `"0xef01…"` to indicate a specific [EIP-7702](./eip-7702.md) delegation. + * A special key `nonce` defines the expected nonce of the account. + * If the value is **hex string**, it is the known storage root hash of that account. + * If the value is an **object**, then it is a mapping where each member is in the format of `"slot": "value"`. + The `value` fields are explicit slot values of the account's storage. + Both `slot` and `value` are hex-encoded strings. + * **blockNumberMin**: minimal block number for inclusion. + * **blockNumberMax**: maximum block number for inclusion. + * **timestampMin**: minimum block timestamp for inclusion. + * **timestampMax**: maximum block timestamp for inclusion. + * **paysCoinbase**: the caller declares the minimum amount paid to the `coinbase` by this transaction, + including gas fees and direct payment. + +Before accepting the request, the block builder or sequencer SHOULD: + +* Check that the block number is within the block range if the block range value was specified. +* Check that the block timestamp is within the timestamp range if the timestamp range was specified. +* For all addresses with a specified storage root hash, validate the current root is unmodified. +* For all addresses with a specified slot values mapping, validate that all these slots hold the exact value specified. + +The sequencer should REJECT the request if any address does not pass the above rules. + +### Return value + +In case of a successful inclusion, the call should return a hash of the newly submitted transaction. +This behaviour is equivalent to the `eth_sendRawTransaction` JSON-RPC API method. + +In case of an immediate failure to validate the transaction's conditions, +the block builder SHOULD return an error with indication of failure reason. + +The error code SHOULD be "-32003 transaction rejected" with reason string describing the cause: +i.e. storage error, out of block/time range, etc. + +In case of repeated failures or `knownAccounts` mapping being too large for the current block builder to handle, +the error code SHOULD be "-32005 limit exceeded" with a description of the error. + +**NOTE:** Same as with the `eth_sendRawTransaction` method, +even if the RPC method call does not resul in an error and the transaction is +initially accepted into the internal block builder's mempool, +the caller MUST NOT assume that a transaction will be included in a block and should monitor the blockchain. + +### Sample request +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "eth_sendRawTransactionConditional", + "params": [ + "0x2815c17b00...", + { + "blockNumberMax": 12345, + "knownAccounts": { + "0xadd1": "0xfedc....", + "0xadd2": { + "0x1111": "0x1234...", + "0x2222": "0x4567..." + } + } + } + ] +} +``` + +### Limitations + +- Callers should not assume that a successful response means the transaction is included. + Specifically, it is possible that a block re-order might remove the transaction or cause it to fail. + +## Rationale + +The `knownAccounts` only allows specifying the exact values for storage slots. +While in some cases specifying `minValue` or `maxValue` for a slot could be useful, +it would significantly increase complexity of the proposed API. +Additionally, determining the validity range for a slot value is a non-trivial task for the sender of a transaction. + +One way to provide a more complex rule for a transaction condition is by specifying the `paysCoinbase` parameter, +and issuing a transfer to the `coinbase` address on some condition. + +## Backwards Compatibility + +This is a proposal for a new API method so no backward compatibility issues are expected. +Existing non-standard implementations of `eth_sendRawTransactionConditional` API may need to be modified in order to +become compatible with the standard. + +## Security Considerations + +The block builder should protect itself against abuse of the API. +Namely, a malicious actor submitting a large number of requests which are known to fail may lead to a denial of service. + +Following is the list of suggested potential mitigation mechanisms: + +* **Throttling**: the block builder should allow a maximum rate of RPC calls per sender. + The block builder may increase that rate after a successful inclusion. + Repeated rejections of transactions should reduce the allowed rate. +* **Arbitrum**-style protection: Arbitrum implemented this API, but they run the storage validation not only + against the current block, but also into past 2 seconds. + This prevents abusing the API for MEV, while making it viable for [ERC-4337](./eip-4337.md) account validation. +* **Fastlane on Polygon** uses it explicitly for ERC-4337, + by checking the submitted UserOperations exist on the public mempool and rejecting the transaction otherwise. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From 3d411a0f35d6947d1872df0c7137e27d0dbb98f8 Mon Sep 17 00:00:00 2001 From: Radek Date: Tue, 29 Oct 2024 15:43:27 +0100 Subject: [PATCH 35/46] Add ERC: ERC-20 Transfer Reference Extension Merged by EIP-Bot. --- ERCS/erc-7699.md | 212 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 ERCS/erc-7699.md diff --git a/ERCS/erc-7699.md b/ERCS/erc-7699.md new file mode 100644 index 0000000000..d078ad2985 --- /dev/null +++ b/ERCS/erc-7699.md @@ -0,0 +1,212 @@ +--- +eip: 7699 +title: ERC-20 Transfer Reference Extension +description: Include a unique identifier (transfer or "payment" reference) for each ERC-20 transaction to associate transfers with orders/invoices. +author: Radek Svarz (@radeksvarz) +discussions-to: https://ethereum-magicians.org/t/erc-7699-erc20-payment-reference-extension/19826 +status: Draft +type: Standards Track +category: ERC +created: 2024-04-26 +requires: 20, 165 +--- + +## Abstract + +The [ERC-20](./eip-20.md) token standard does not provide a built-in mechanism for including a payment transfer reference (message for recipient) in token transfers. This proposal extends the existing ERC-20 token standard by adding minimal methods to include a transfer reference in token transfers and transferFrom operations. The addition of a reference can help users, merchants, and service providers to associate and reconcile individual transactions with specific orders or invoices. + +## Motivation + +The primary motivation for this proposal is to improve the functionality of the ERC-20 token standard by providing a mechanism for including a payment reference in token transfers, similar to the traditional finance systems where payment references are commonly used to associate and reconcile transactions with specific orders, invoices or other financial records. + +Currently, users and merchants who want to include a payment reference in their transactions must rely on off chain external systems or custom payment proxy implementations. In traditional finance systems, payment references are often included in wire transfers and other types of electronic payments, making it easy for users and merchants to manage and reconcile their transactions. Such as: + + - SWIFT MT103: field 70 “Remittance Information” is commonly used for such content (e.g " PAYMENT FOR INVOICE 998877"). There is also field 72 “Sender to receiver information”. + - ISO 20022 (for SEPA): PAIN.001 has field called RmtInf (Remittance Information) + +By extending the existing ERC-20 token standard with payment transfer reference capabilities, this proposal will help bridge the gap between traditional finance systems and the world of decentralized finance, providing a more seamless experience for users, merchants, and service providers alike. + +## Specification + +The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119. + +Any contract complying with ERC-20 when extended with this ERC, MUST implement the following interface: +``` +// The EIP-165 identifier of this interface is 0x1522573a + +interface IERC7699 { + +function transfer(address to, uint256 amount, bytes calldata transferReference) external returns (bool); + +function transferFrom(address from, address to, uint256 amount, bytes calldata transferReference) external returns (bool); + +event TransferReference(bytes32 indexed loggedReference); + +} +``` + +These `transfer` and `transferFrom` functions, in addition to the standard transfer behaviour, MUST emit a `transferReference` event with a `loggedReference` parameter (with only exception defined below). + +The corresponding ERC-20 `Transfer` event MUST be emitted following the `TransferReference` event, ideally immediately afterwards for the client to be able to seek the associated `Transfer` event log record. + +Emitted `loggedReference` MIGHT be the exact copy of the `transferReference` (when less then 33 bytes) or the derived data from the rich `transferReference` structure and other processing. This is up to the implementer. One MUST NOT expect the `transferReference` and `loggedReference` data are equal. + +The `loggedReference` parameter MAY contain any data of bytes32 type. + +The `transferReference` parameter MAY be empty. In this case and only in this case the `TransferReference` event MUST NOT be emitted, effectively mimicking the regular ERC-20 transfer without any transfer reference. + +The `transferReference` parameter is not limited in length by design, users are motivated to keep it short due to calldata and execution gas costs. + +The `TransferReference` event MUST NOT be anonymous. This is to ensure that the event signature is logged and can be used as a filter. + +Transfers of 0 amount MUST be treated as normal transfers and fire the `TransferReference` event alike. + +## Rationale + +### Parameter name + +The choice to name the added parameter `transferReference` was made to align with traditional banking terminology, where payment references are widely used to associate and reconcile transactions with specific orders, invoices or other financial records. + +The `transferReference` parameter name also helps to clearly communicate the purpose of the parameter and its role in facilitating the association and reconciliation of transactions. By adopting terminology that is well-established in the financial industry, the proposal aims to foster a greater understanding and adoption of the extended ERC-20 token standard. + +### Parameter type + +The `transferReference` type is bytes. + +The `transferReference` type was initially considered to be bytes32 in order to motivate users to either use short references (as is common in TradFi) or rather use Keccak 256 hash of the reference content. Conclusion was that the options should rather be kept open to be able to call with structured data; such as passing reference data including a signature enabling extra processing checks. + +### Emitted data + +The `loggedReference` type is bytes32. + +It was considered to log a reference in the form of `bytes calldata`. However, the reference content would be hashed in the event log due to the log topic indexing required for the even subscription filters. The resulting logged topic is always in the form of bytes32. Bytes32 type enables to log publicly readable (non hashed) reference content up to 32 bytes long. + +## Backwards Compatibility + +This extension is fully backwards compatible with the existing ERC-20 token standard. The new functions can be used alongside the existing transfer and transferFrom functions. Existing upgradable ERC-20 tokens can be upgraded to include the new functionality without impact on the storage layout; new ERC-20 tokens can choose to implement the payment reference features based on their specific needs. + +## Reference Implementation + +``` +// SPDX-License-Identifier: CC0-1.0 +pragma solidity >=0.8.4 <0.9.0; + +import {ERC20} from "@openzeppelin/token/ERC20/ERC20.sol"; + +interface IERC7699 { + /** + * @notice Emitted when a non-empty `transferReference` is added to the `transfer` call. + */ + event TransferReference(bytes32 indexed loggedReference); + + /** + * @notice Moves `amount` tokens from the caller's account to `to` with `transferReference`. + * + * @dev Returns a boolean value indicating whether the operation succeeded. + * + * MUST emit this ERCS's {TransferReference} event followed by a corresponding {ERC20.Transfer} event + * (to comply with ERC-20). + */ + function transfer(address to, uint256 amount, bytes calldata transferReference) external returns (bool); + + /** + * @notice Moves `amount` tokens from `from` to `to` with `transferReference` using the + * allowance mechanism. `amount` is then deducted from the caller's allowance. + * + * @dev Returns a boolean value indicating whether the operation succeeded. + * + * MUST emit this ERCS's {TransferReference} event followed by a corresponding {ERC20.Transfer} event + * (to comply with ERC-20). + */ + function transferFrom(address from, address to, uint256 amount, bytes calldata transferReference) + external + returns (bool); +} + +/** + * @dev Implementation of the ERC20 transfer reference extension. + */ +contract ERC20TransferReference is ERC20, IERC7699 { + constructor() ERC20("ERC20 Transfer Reference Example", "TXRE") { + _mint(msg.sender, 987654321 * 1e18); + } + + /** + * @dev Emits `TransferReference` event with derived `loggedReference` data + */ + function _logReference(bytes calldata transferReference) internal virtual { + // MUST NOT emit when transferReference is empty + if (transferReference.length > 0) { + // Effectively extract first 32 bytes from transferReference calldata bytes + // Note: This is the example. Derivation of the loggedReference is fully up to the implementation. + // E.g. keccak hash of the whole transferReference, etc. + bytes32 loggedReference; + // solhint-disable-next-line no-inline-assembly + assembly { + loggedReference := calldataload(transferReference.offset) + } + + emit TransferReference(loggedReference); + } + } + + /** + * @notice A standard ERC20 token transfer with an optional transfer reference + * @dev The underlying `transfer` function is assumed to handle the actual token transfer logic. + * @param to The address of the recipient where the tokens will be sent. + * @param amount The number of tokens to be transferred. + * @param transferReference A bytes field to include a transfer reference, reference signature or other relevant + * reference data. + * @return A boolean indicating whether the transfer was successful. + */ + function transfer(address to, uint256 amount, bytes calldata transferReference) public virtual returns (bool) { + _logReference(transferReference); + + // ERC20.Transfer event is emitted immediately after TransferReference event + return transfer(to, amount); + } + + /** + * @notice A delegated token transfer with an optional transfer reference + * @dev Requires prior approval from the token owner. The underlying `transferFrom` function is assumed to handle + * allowance and transfer logic. + * @param from The address of the token owner who has authorized the transfer. + * @param to The address of the recipient where the tokens will be sent. + * @param amount The number of tokens to be transferred. + * @param transferReference A bytes field to include a transfer reference, reference signature or other relevant + * reference data. + * @return A boolean indicating whether the transfer was successful. + */ + function transferFrom(address from, address to, uint256 amount, bytes calldata transferReference) + public + virtual + returns (bool) + { + _logReference(transferReference); + + // ERC20.Transfer event is emitted immediately after TransferReference event + return transferFrom(from, to, amount); + } +} + +``` + +## Security Considerations + +### Privacy Considerations + +Reference data privacy: Including payment references in token transfers may expose sensitive information about the transaction or the parties involved. Implementers and users SHOULD carefully consider the privacy implications and ensure that payment references do not reveal sensitive information. To mitigate this risk, implementers can consider using encryption or other privacy-enhancing techniques to protect payment reference data. + +Example: With reference 0x20240002 logged, transaction is publicly exposing that this is related to the second invoice of the recipient in 2024. + +### Manipulation of payment references +There is no validation of the reference data dictated by this ERC. Malicious actors might attempt to manipulate payment references to mislead users, merchants, or service providers. This can lead to: + +1. **Legal risks**: The beneficiary may face legal and compliance risks if the attacker uses illicit funds, potentially impersonating or flagging the beneficiary of involvement in money laundering or other illicit activities. + +2. **Disputes and refunds**: The user might discover they didn't make the payment, request a refund or raise a dispute, causing additional administrative work for the beneficiary. + +To mitigate this risk, implementers can consider using methods to identify proper sender and to generate unique and verifiable related payment references. However such implementations are not in the scope of this standard and rather extend it. + +## Copyright +Copyright and related rights waived via [CC0](../LICENSE.md). From fc8c30eb0213816230d3bb64b2326dec2d50b460 Mon Sep 17 00:00:00 2001 From: Dexaran Date: Tue, 29 Oct 2024 14:49:08 +0000 Subject: [PATCH 36/46] Update ERC-7417: Move to Review Merged by EIP-Bot. --- ERCS/erc-7417.md | 173 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 123 insertions(+), 50 deletions(-) diff --git a/ERCS/erc-7417.md b/ERCS/erc-7417.md index 5f2af30f98..46a2292aa1 100644 --- a/ERCS/erc-7417.md +++ b/ERCS/erc-7417.md @@ -4,7 +4,7 @@ title: Token Converter description: Smart-contract service that converts token of one ERC version to another author: Dexaran (@Dexaran) discussions-to: https://ethereum-magicians.org/t/token-standard-converter/15252 -status: Draft +status: Review type: Standards Track category: ERC created: 2023-07-27 @@ -19,25 +19,47 @@ In order to perform the conversion, a user must deposit tokens of one standard t ## Motivation -This proposal introduces a concept of token standard upgrading procedure driven by a specialized smart-contract which can convert tokens of one standard to another at any time as well as create an alternative version of any existing token of the older standard. +This proposal introduces a concept of a token standard upgrading procedure driven by a specialized smart-contract which can convert tokens of one standard to another at any time. -Currently some tokens are available on different chains in different standards, for example most exchanges support [ERC-20](./eip-20.md) USDT, TRX USDT, BEP-20 USDT and all this tokens are in fact the same USDT token. This proposal is intended to introduce a concept where there can be a [ERC-20](./eip-20.md) USDT and [ERC-223](./eip-223.md) USDT available on Ethereum mainnet at the same time and both can co-exist. +Currently some tokens are available on different chains in different standards, for example most exchanges support [ERC-20](./eip-20.md) USDT, TRX USDT, BEP-20 USDT and all this tokens are in fact the same USDT token. This proposal is intended to introduce a concept where there can be a [ERC-20](./eip-20.md) USDT and [ERC-223](./eip-223.md) USDT available on Ethereum mainnet at the same time and these would be freely interchangeable. The address of the deployed Token Converter must be described here as to solve the trust issues for the token developers and help them figure out a proper way of interacting with the Converter. +As Ethereum already has an established ecosystem of tokens and [ERC-20](./eip-20.md) is the most adopted standard at the moment the lack of defined migration processes can be a bottleneck for newer standards adoption. This proposal addresses the problem of coordinating the upgrading process and addresses the backwards compatibility problems for [ERC-20](./eip-20.md) and [ERC-223](./eip-223.md) tokens. + +The Token Converter is supposed to allow anyone to create an alternative version of an existing token implemented in a different standard. This proposal focuses on [ERC-20](./eip-20.md) and [ERC-223](./eip-223.md) standards and takes into account the specifics of this particular token standards. It is assumed that the most common case would be creation of [ERC-223](./eip-223.md) version for an existing [ERC-20](./eip-20.md) token. + +The implementation of this service is an alternative to convincing each token developer to choose an alternative standard at the moment of the token deployment or during the development stage of their project. With this service there will be no need to choose one standard and stick with it as every token can be available in both concurrently. + +The implementation of this Token Converter service is supposed to be a contract deployed on Ethereum mainnet once and forever. It's address will be provided in the text of this proposal as to avoid any potential trust issues and assure the developers that the service they are interacting with is exactly the one which drives the conversion process of existing tokens. + +All the [ERC-223](./eip-223.md) tokens created by the Token Converter will be identical in a way that they all implement the same functions, which return the same values and there is no ambiguity there. This helps to avoid problems where a token deployed during the early stage of a token standard adoption may implement it improperly or there can be an ambiguity in the standard itself that would allow developers to implement tokens of one standard in different ways. + +For example it was a common case with [ERC-20](./eip-20.md) where developers could implement custom logic of the `transfer` function and mess the return values. The [ERC-20](./eip-20.md) specification declares that a `transfer` function MUST return a `bool` value, however in practice we have three different types of [ERC-20](./eip-20.md) tokens which are not compatible with each other: + +1. [ERC-20](./eip-20.md) tokens that return `true` on success and revert on an error. +2. [ERC-20](./eip-20.md) tokens that return `true` on success and `false` on an error without reverting the transaction. +3. [ERC-20](./eip-20.md) tokens that don't have return values and revert on an error. + +Technically the third category of tokens is not compatible with [ERC-20](./eip-20.md) standard. However, USDT token deployed on Ethereum mainnet at `0xdac17f958d2ee523a2206206994597c13d831ec7` address does not implement return values and it is one of the most used tokens and it is not an option to deny supporting USDT due to it's improper implementation of the standard. + +The Token Converter eliminates the issue where different development teams may implement the standard with slight modifications and result in a situation where we would have different versions of the same standard on the mainnet. + +At the same time the Converter enables the concurrent token support in other smart-contracts, such as decentralized exchanges. The Converter can guarantee that a pair of two tokens one of which is a wrapper for another is in fact the same token that can be converted from one standard to another at any time. This enables the creation of liquidity pools where two different tokens are dealt with as if they were one token. + ## Specification The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. -The Token Converter system comprises two main parts: +The Token Converter system comprises two main components: -- Converter contract +- Converter contract. -- [ERC-223](./eip-223.md) wrapper contract for each [ERC-20](./eip-20.md) token +- Wrapper contracts. Each original token can have exactly one wrapper of each standard. Converter contract can deploy new [ERC-223](./eip-223.md) wrapper contracts for any [ERC-20](./eip-20.md) token that does not have a [ERC-223](./eip-223.md) wrapper currently. There MUST be exactly one [ERC-223](./eip-223.md) wrapper for each [ERC-20](./eip-20.md) token. -Converter contract MUST accept deposits of [ERC-20](./eip-20.md) tokens and send [ERC-223](./eip-223.md) tokens to the depositor at 1:1 ratio. Upon depositing 1234 units of `ERC-20 token_A` the depositor MUST receive exactly 1234 units of `ERC-223 token_A`. This is done by issuing new [ERC-223](./eip-223.md) tokens at the moment of [ERC-20](./eip-20.md) deposit. The original [ERC-20](./eip-20.md) tokens MUST be frozen in the Converter contract and available for claiming back. +Converter contract MUST accept deposits of [ERC-20](./eip-20.md) tokens and send [ERC-223](./eip-223.md) tokens to the depositor at 1:1 ratio. Upon depositing 1234 units of `ERC20 token_A` the depositor MUST receive exactly 1234 units of `ERC223 token_A`. This is done by issuing new [ERC-223](./eip-223.md) tokens at the moment of [ERC-20](./eip-20.md) deposit. The original [ERC-20](./eip-20.md) tokens MUST be frozen in the Converter contract and available for claiming back. Converter contract MUST accept deposits of [ERC-223](./eip-223.md) tokens and send [ERC-20](./eip-20.md) tokens to the depositor at 1:1 ratio. This is done by releasing the original [ERC-20](./eip-20.md) tokens at the moment of [ERC-223](./eip-223.md) deposit. The deposited [ERC-223](./eip-223.md) tokens must be burned. @@ -193,7 +215,7 @@ In order to convert [ERC-20](./eip-20.md) tokens to [ERC-223](./eip-223.md) the 2. Wait for the transaction with `approve` to be submitted to the blockchain. 3. Call the `convertERC20toERC223` function of the Token Converter contract. -### Converting [ERC-223](./eip-223.md) tokens back to [ERC-20](./eip-20.md) +### Converting [ERC-223](./eip-223.md) wrapper tokens back to [ERC-20](./eip-20.md) In order to convert [ERC-20](./eip-20.md) tokens to [ERC-223](./eip-223.md) the token holder should: @@ -201,27 +223,77 @@ In order to convert [ERC-20](./eip-20.md) tokens to [ERC-223](./eip-223.md) the ## Rationale -As Ethereum already has an established ecosystem of tokens and [ERC-20](./eip-20.md) is the most adopted standard at the moment the lack of defined migration processes can be a bottleneck for newer standards adoption. This proposal addresses the problem of coordinating the upgrading process and addresses the backwards compatibility problems for [ERC-20](./eip-20.md) and [ERC-223](./eip-223.md) tokens. +### Support of [ERC-223](./eip-223.md) original tokens -The Token Converter is supposed to allow anyone to create an alternative version of an existing token implemented in a different standard. This proposal focuses on [ERC-20](./eip-20.md) and [ERC-223](./eip-223.md) standards and takes into account the specifics of this particular token standards. It is assumed that the most common case would be creation of [ERC-223](./eip-223.md) version for an existing [ERC-20](./eip-20.md) token. +Two methods of implementing a Token Converter service were considered: (1) a converter that can only create [ERC-223](./eip-223.md) versions of the existing [ERC-20](./eip-20.md) tokens, and (2) a converter that can create both versions ([ERC-20](./eip-20.md) and [ERC-223](./eip-223.md)) of any original token. -The implementation of this service is an alternative to convincing each token developer to choose an alternative standard at the moment of the token deployment or during the development stage of their project. With this service there will be no need to choose one standard and stick with it as every token can be available in both concurrently. +The first approach would encourage developers to always deploy an original token as [ERC-20](./eip-20.md) and then create it's [ERC-223](./eip-223.md) version in the converter. If it would happen that some developers may consider [ERC-223](./eip-223.md) as their original standard then they would be left with the problem of creating their custom [ERC-20](./eip-20.md) version of the token. In addition, if any third party contracts like liquidity pools are using the proposed Token Converter to ensure that a token can be listed on a DEX with two versions and both can be combined within one pool - then such contract would not be able to recognize any original [ERC-223](./eip-223.md) token and it's [ERC-20](./eip-20.md) version as a valid pair of contracts that represent one token available in two standards. -The implementation of this Token Converter service is supposed to be a contract deployed on Ethereum mainnet once and forever. It's address will be provided in the text of this proposal as to avoid any potential trust issues and assure the developers that the service they are interacting with is exactly the one which drives the conversion process of existing tokens. +For that reason it was decided to go with the second approach where the Converter can create [ERC-20](./eip-20.md) wrappers for original [ERC-223](./eip-223.md) tokens. -All the [ERC-223](./eip-223.md) tokens created by the Token Converter will be identical in a way that they all implement the same functions, which return the same values and there is no ambiguity there. This helps to avoid problems where a token deployed during the early stage of a token standard adoption may implement it improperly or there can be an ambiguity in the standard itself that would allow developers to implement tokens of one standard in different ways. +### Support of `approve` & `transferFrom` functions in the [ERC-223](./eip-223.md) wrapper tokens -For example it was a common case with [ERC-20](./eip-20.md) where developers could implement custom logic of the `transfer` function and mess the return values. The [ERC-20](./eip-20.md) specification declares that a `transfer` function MUST return a `bool` value, however in practice we have three different types of [ERC-20](./eip-20.md) tokens which are not compatible with each other: +This functions are superfluous for a [ERC-223](./eip-223.md) token since the `transfer` function can be used to deposit tokens of this standard to contracts. The current ecosystem is built for [ERC-20](./eip-20.md) tokens however and there are plenty of multisig contracts that rely on accepting tokens deposited without any callback with an assumption that it is not necessary for a multisig to count the amount of tokens it stores. -1. [ERC-20](./eip-20.md) tokens that return `true` on success and revert on an error. -2. [ERC-20](./eip-20.md) tokens that return `true` on success and `false` on an error without reverting the transaction. -3. [ERC-20](./eip-20.md) tokens that don't have return values and revert on an error. +There can be any other contracts and scenarios where it would be necessary to deposit a token to a contract which is relying on an assumption that tokens are deposited without invoking a callback in the recipient. As the result we can expect that any original deployed [ERC-223](./eip-223.md) tokens will support this functions, as token developers strive for backward compatibility with the existing ecosystem. In order to make tokens deployed by the converter a reference implementation for developers that can be used without any modifications it was decided to support this functions in the [ERC-223](./eip-223.md) wrapper contracts. -Technically the third category of tokens is not compatible with [ERC-20](./eip-20.md) standard. However, USDT token deployed on Ethereum mainnet at `0xdac17f958d2ee523a2206206994597c13d831ec7` address does not implement return values and it is one of the most used tokens and it is not an option to deny supporting USDT due to it's improper implementation of the standard. +`transferFrom` function does not support error handling and this needs to be taken into account. It is possible to deposit tokens to a contract which is not designed to receive them by approving X tokens to your own address and then calling a `transferFrom(self, contract, X)`. The tokens will be deposited regardless of whether the recipient contract is designed to hold/receive tokens or not. The tokens may get permanently stuck if the recipient contract did not implement the extraction functions. The `approve` & `transferFrom` function is not the default method of token transferring however and it is not directly used by any wallets and any other software that manages tokens. The `transfer` function (which is safe) is used instead. The `transferFrom` function is supposed to be invoked by a contract to pull tokens from the approver. -The Token Converter eliminates the issue where different development teams may implement the standard with slight modifications and result in a situation where we would have different versions of the same standard on the mainnet. +As the result, the `approve` & `transferFrom` transferring method must be avoided with [ERC-223](./eip-223.md) tokens whenever possible. + +### Modified transfer events of the [ERC-223](./eip-223.md) token + +The pure [ERC-223](./eip-223.md) token implementation has the following event emitted on a token transfer: `event Transfer(address indexed _from, address indexed _to, uint256 _value, bytes _data)`. This events are different from ones emitted by [ERC-20](./eip-20.md) tokens and may not be properly recognized by existing blockchain explorers, wallets and other services that browse token transfers history. -At the same time the Converter enables the concurrent token support in other smart-contracts, such as decentralized exchanges. The Converter can guarantee that a pair of two tokens one of which is a wrapper for another is in fact the same token that can be converted from one standard to another at any time. This enables the creation of liquidity pools where two different tokens are dealt with as if they were one token while in fact these are exactly one token available in different standards. +It was considered that events are not an important part of the standard as these do not affect the logic of the token, it's workflow and it's security. When developing the Converter it was decided to prioritize compatibility with existing ecosystem. + +### `standard()` function usage for the introspection + +The main existing method of introspection is currently [ERC-165](./eip-165.md) which inspects the signatures of functions implemented in a contract. It is not possible to differentiate an [ERC-20](./eip-20.md) token from an [ERC-223](./eip-223.md) token by just browsing functions that they implement without digging their internal logic. + +Here is a token and it is not possible to identify if it should be dealt with as [ERC-20](./eip-20.md) or [ERC-223](./eip-223.md) because it depends on the actual implemenation of it's `transfer` function logic. + +```solidity +abstract contract Token { + function name() external virtual returns (string memory); + function symbol() external virtual returns (string memory); + function decimals() external virtual returns (uint8); + + function transfer(address, uint256) external virtual returns (bool); + function approve(address, uint256) external virtual returns (bool); + function transferFrom(address, address, uint256) external virtual returns (bool); +} +``` + +In case of this implementation the token will behave as [ERC-20](./eip-20.md): + +```solidity + function transfer(address _to, uint256 _amount) external virtual returns (bool) + { + balances[msg.sender] -= _amount; + balances[_to] += _amount; + } +} +``` + +In case of this implementation the token will behave as [ERC-223](./eip-223.md): + +```solidity + function transfer(address _to, uint256 _amount) external virtual returns (bool) + { + balances[msg.sender] -= _amount; + balances[_to] += _amount; + if(_to.isContract()) + { + IERC223Recipient(_to).tokenReceived(msg.sender, _amount, hex"000000"); + } + } +} +``` + +Also, there are plenty of tokens that do not implement [ERC-165](./eip-165.md) introspection at all. As the result it was decided to implement a special `standard() returns (uint32)` function in all [ERC-223](./eip-223.md) wrappers created by the Converter and assume that original [ERC-223](./eip-223.md) tokens may explicityly declare themselves as [ERC-223](./eip-223.md) by implementing the same function too. It is assumed that if a token does not implement this function then it is [ERC-20](./eip-20.md). + +This method of token standard introspection is more precise than [ERC-165](./eip-165.md). ## Backwards Compatibility @@ -233,7 +305,6 @@ This service is the first of its kind and therefore does not have any backwards ```solidity -// SPDX-License-Identifier: GPL-3.0 pragma solidity =0.8.19; @@ -324,7 +395,7 @@ interface standardERC20 } /** - * @dev Interface of the ERC20 standard as defined in the EIP. + * @dev Interface of the ERC20 standard. */ interface IERC223WrapperToken { function name() external view returns (string memory); @@ -365,9 +436,9 @@ interface IERC20WrapperToken { contract ERC20Rescue { - // ERC-20 tokens can get stuck on a contracts balance due to lack of error handling. + // ERC20 tokens can get stuck on a contracts balance due to lack of error handling. // - // The author of the ERC-7417 can extract ERC-20 tokens if they are mistakenly sent + // The author of the ERC7417 can extract ERC20 tokens if they are mistakenly sent // to the wrapper-contracts balance. // Contact dexaran@ethereumclassic.org address public extractor = 0x01000B5fE61411C466b70631d7fF070187179Bbf; @@ -422,7 +493,7 @@ contract ERC223WrapperToken is IERC223, ERC165, ERC20Rescue } /** - * @dev Standard ERC-223 transfer function. + * @dev Standard ERC223 transfer function. * Calls _to if it is a contract. Does not transfer tokens to contracts * which do not explicitly declare the tokenReceived function. * @param _to - transfer recipient. Can be contract or EOA. @@ -433,19 +504,23 @@ contract ERC223WrapperToken is IERC223, ERC165, ERC20Rescue { balances[msg.sender] = balances[msg.sender] - _value; balances[_to] = balances[_to] + _value; + if (msg.value > 0) + { + (bool sent, bytes memory data) = _to.call{value: msg.value}(""); + require(sent); + } if(Address.isContract(_to)) { IERC223Recipient(_to).tokenReceived(msg.sender, _value, _data); } - if (msg.value > 0) payable(_to).transfer(msg.value); emit Transfer(msg.sender, _to, _value, _data); - emit Transfer(msg.sender, _to, _value); // Old ERC-20 compatible event. Added for backwards compatibility reasons. + emit Transfer(msg.sender, _to, _value); // Old ERC20 compatible event. Added for backwards compatibility reasons. return true; } /** - * @dev Standard ERC-223 transfer function without _data parameter. It is supported for - * backwards compatibility with ERC-20 services. + * @dev Standard ERC223 transfer function without _data parameter. It is supported for + * backwards compatibility with ERC20 services. * Calls _to if it is a contract. Does not transfer tokens to contracts * which do not explicitly declare the tokenReceived function. * @param _to - transfer recipient. Can be contract or EOA. @@ -460,13 +535,13 @@ contract ERC223WrapperToken is IERC223, ERC165, ERC20Rescue IERC223Recipient(_to).tokenReceived(msg.sender, _value, _empty); } emit Transfer(msg.sender, _to, _value, _empty); - emit Transfer(msg.sender, _to, _value); // Old ERC-20 compatible event. Added for backwards compatibility reasons. + emit Transfer(msg.sender, _to, _value); // Old ERC20 compatible event. Added for backwards compatibility reasons. return true; } function name() public view override returns (string memory) { return IERC20Metadata(wrapper_for).name(); } - function symbol() public view override returns (string memory) { return string.concat(IERC20Metadata(wrapper_for).name(), "223"); } + function symbol() public view override returns (string memory) { return string.concat(IERC20Metadata(wrapper_for).symbol(), "223"); } function decimals() public view override returns (uint8) { return IERC20Metadata(wrapper_for).decimals(); } function standard() public pure returns (uint32) { return 223; } function origin() public view returns (address) { return wrapper_for; } @@ -496,16 +571,14 @@ contract ERC223WrapperToken is IERC223, ERC165, ERC20Rescue _totalSupply -= _quantity; } - // ERC-20 functions for backwards compatibility. + // ERC20 functions for backwards compatibility. function allowance(address owner, address spender) public view virtual returns (uint256) { return allowances[owner][spender]; } function approve(address _spender, uint _value) public returns (bool) { - - // Safety checks. - require(_spender != address(0), "ERC-223: Spender error."); + require(_spender != address(0), "ERC223: Spender error."); allowances[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); @@ -515,7 +588,7 @@ contract ERC223WrapperToken is IERC223, ERC165, ERC20Rescue function transferFrom(address _from, address _to, uint _value) public returns (bool) { - require(allowances[_from][msg.sender] >= _value, "ERC-223: Insufficient allowance."); + require(allowances[_from][msg.sender] >= _value, "ERC223: Insufficient allowance."); balances[_from] -= _value; allowances[_from][msg.sender] -= _value; @@ -547,7 +620,7 @@ contract ERC20WrapperToken is IERC20, ERC165, ERC20Rescue function balanceOf(address _owner) public view override returns (uint256) { return balances[_owner]; } function name() public view returns (string memory) { return IERC20Metadata(wrapper_for).name(); } - function symbol() public view returns (string memory) { return string.concat(IERC223(wrapper_for).name(), "20"); } + function symbol() public view returns (string memory) { return string.concat(IERC223(wrapper_for).symbol(), "20"); } function decimals() public view returns (uint8) { return IERC20Metadata(wrapper_for).decimals(); } function totalSupply() public view override returns (uint256) { return _totalSupply; } function origin() public view returns (address) { return wrapper_for; } @@ -589,7 +662,7 @@ contract ERC20WrapperToken is IERC20, ERC165, ERC20Rescue // Safety checks. - require(_spender != address(0), "ERC-20: Spender error."); + require(_spender != address(0), "ERC20: Spender error."); allowances[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); @@ -599,7 +672,7 @@ contract ERC20WrapperToken is IERC20, ERC165, ERC20Rescue function transferFrom(address _from, address _to, uint _value) public returns (bool) { - require(allowances[_from][msg.sender] >= _value, "ERC-20: Insufficient allowance."); + require(allowances[_from][msg.sender] >= _value, "ERC20: Insufficient allowance."); balances[_from] -= _value; allowances[_from][msg.sender] -= _value; @@ -616,7 +689,7 @@ contract TokenStandardConverter is IERC223Recipient event ERC223WrapperCreated(address indexed _token, address indexed _ERC223Wrapper); event ERC20WrapperCreated(address indexed _token, address indexed _ERC20Wrapper); - mapping (address => ERC223WrapperToken) public erc223Wrappers; // A list of token wrappers. First one is ERC-20 origin, second one is ERC-223 version. + mapping (address => ERC223WrapperToken) public erc223Wrappers; // A list of token wrappers. First one is ERC20 origin, second one is ERC223 version. mapping (address => ERC20WrapperToken) public erc20Wrappers; mapping (address => address) public erc223Origins; @@ -644,20 +717,20 @@ contract TokenStandardConverter is IERC223Recipient } function predictWrapperAddress(address _token, - bool _isERC20 // Is the provided _token a ERC-20 or not? - // If it is set as ERC-20 then we will predict the address of a - // ERC-223 wrapper for that token. - // Otherwise we will predict ERC-20 wrapper address. + bool _isERC20 // Is the provided _token a ERC20 or not? + // If it is set as ERC20 then we will predict the address of a + // ERC223 wrapper for that token. + // Otherwise we will predict ERC20 wrapper address. ) view external returns (address) { bytes memory _bytecode; if(_isERC20) { - _bytecode= type(ERC223WrapperToken).creationCode; + _bytecode = type(ERC223WrapperToken).creationCode; } else { - _bytecode= type(ERC20WrapperToken).creationCode; + _bytecode = type(ERC20WrapperToken).creationCode; } bytes32 hash = keccak256( @@ -673,8 +746,8 @@ contract TokenStandardConverter is IERC223Recipient { require(erc223Origins[msg.sender] == address(0), "Error: creating wrapper for a wrapper token."); // There are two possible cases: - // 1. A user deposited ERC-223 origin token to convert it to ERC-20 wrapper - // 2. A user deposited ERC-223 wrapper token to unwrap it to ERC-20 origin. + // 1. A user deposited ERC223 origin token to convert it to ERC20 wrapper + // 2. A user deposited ERC223 wrapper token to unwrap it to ERC20 origin. if(erc20Origins[msg.sender] != address(0)) { @@ -690,8 +763,8 @@ contract TokenStandardConverter is IERC223Recipient } // Otherwise origin for the sender token doesn't exist // There are two possible cases: - // 1. ERC-20 wrapper for the deposited token exists - // 2. ERC-20 wrapper for the deposited token doesn't exist and must be created. + // 1. ERC20 wrapper for the deposited token exists + // 2. ERC20 wrapper for the deposited token doesn't exist and must be created. else if(address(erc20Wrappers[msg.sender]) == address(0)) { // Create ERC-20 wrapper if it doesn't exist. From ad6820e48b659ca116946dddb85af9e8e1c22dc3 Mon Sep 17 00:00:00 2001 From: "0xneves.eth" <90667119+0xneves@users.noreply.github.com> Date: Tue, 29 Oct 2024 12:03:45 -0300 Subject: [PATCH 37/46] Add ERC: Grant Registry Merged by EIP-Bot. --- ERCS/erc-7794.md | 774 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 774 insertions(+) create mode 100644 ERCS/erc-7794.md diff --git a/ERCS/erc-7794.md b/ERCS/erc-7794.md new file mode 100644 index 0000000000..a25019dd97 --- /dev/null +++ b/ERCS/erc-7794.md @@ -0,0 +1,774 @@ +--- +eip: 7794 +title: Grant Registry +description: A cross-network registry contract to manage and track grants, enhancing transparency and interoperability for grant programs. +author: Guilherme Neves (@0xneves) +discussions-to: https://ethereum-magicians.org/t/erc-7794-grant-registry/20791 +status: Draft +type: Standards Track +category: ERC +created: 2024-10-22 +--- + +## Abstract + +This proposal introduces a Grant Registry contract intended for managing financial, research, or project-based grants that provide funding for projects across multiple blockchains. The contract standardizes the registration, management, and tracking of these grants by organizing data into distinct categories, enabling clear separation between immutable fields and mutable fields. It supports modular disbursement tracking and allows for external links to off-chain documentation. This registry emits lifecycle events, enabling external protocols to efficiently access grant data, which promotes transparency, interoperability, and enhanced insights into grant program performance. + +## Motivation + +The Ethereum ecosystem currently lacks a standardized way to manage and track grants across different chains and programs, leading to inefficiencies and fragmentation. Each grant program has its own distinct interface, processes, and management mechanisms, which creates barriers for both funders and grantees. These issues hinder transparency, complicate the tracking of fund disbursements, and make it difficult to evaluate the overall effectiveness of grant programs across different networks. + +The lack of interoperability between grant programs further exacerbates the problem, as projects and contributors often work across multiple blockchains. This makes it challenging to aggregate data, monitor milestones, and assess grantee performance in a consistent manner. + +The Grant Registry contract solves these issues by introducing a unified standard that ensures all grants can be registered, tracked, and managed consistently, regardless of the underlying chain or program. This approach not only simplifies the lifecycle management of grants but also fosters better collaboration between communities, allowing for more competitiveness and better tracking of progress. Additionally, the standardization of data opens the door for more insightful analytics, enabling protocols to measure the impact of grants in a much more streamlined and transparent way. + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +### **Contract Interface** + +```solidity +// SPDX-License-Identifier: CC0-1.0 +pragma solidity ^0.8.20; + +interface IGrantRegistry { + /** + * @dev Thrown when the community name length is invalid (e.g., too short or too long). + */ + error InvalidCommunityNameLength(); + + /** + * @dev Thrown when the caller is not the current grant manager. + */ + error InvalidGrantManager(); + + /** + * @dev Thrown when a grant is already registered with the provided ID. + */ + error GrantAlreadyRegistered(); + + /** + * @dev Thrown when attempting to add a grantee that is already present in the set. + */ + error GranteeAlreadyAdded(); + + /** + * @dev Thrown when attempting to remove a grantee that is not found in the set. + */ + error GranteeNotFound(); + + /** + * @dev Thrown when attempting to add or reference an invalid external link. + */ + error InvalidExternalLink(); + + /** + * @dev Thrown when an invalid index is provided (e.g., out of bounds for an array). + */ + error InvalidIndex(); + + /** + * @dev Thrown when a milestone date is invalid (e.g., earlier than the grant's start date). + */ + error InvalidStartDate(); + + /** + * @dev Thrown when attempting to add a milestone date that is already present. + */ + error MilestoneDateAlreadyAdded(); + + /** + * @dev Thrown when attempting to remove or reference a milestone date that is not found. + */ + error MilestoneDateNotFound(); + + /** + * @dev Emitted when a new grant is registered. + * @param grantId The unique identifier for the grant. + * @param id The grant's unique numeric ID. + * @param chainid The chain ID where the grant is registered. + * @param community The name of the community that issued the grant. + * @param grantManager The address of the grant manager. + */ + event GrantRegistered( + bytes32 indexed grantId, + uint256 indexed id, + uint256 chainid, + string indexed community, + address grantManager + ); + + /** + * @dev Emitted when the ownership of a grant is transferred. + * @param grantId The unique identifier of the grant. + * @param newGrantManager The address of the new grant manager. + */ + event OwnershipTransferred( + bytes32 indexed grantId, + address indexed newGrantManager + ); + + /** + * @dev Emitted when a new grantee is added to the grant. + * @param grantId The unique identifier of the grant. + * @param grantee The address of the new grantee. + */ + event GranteeAdded(bytes32 indexed grantId, address indexed grantee); + + /** + * @dev Emitted when a grantee is removed from the grant. + * @param grantId The unique identifier of the grant. + * @param grantee The address of the removed grantee. + */ + event GranteeRemoved(bytes32 indexed grantId, address indexed grantee); + + /** + * @dev Emitted when the start date of a grant is set. + * @param grantId The unique identifier of the grant. + * @param startDate The timestamp representing the start date. + */ + event StartDateSet(bytes32 indexed grantId, uint256 startDate); + + /** + * @dev Emitted when a new milestone date is added to the grant. + * @param grantId The unique identifier of the grant. + * @param milestoneDate The timestamp of the added milestone. + */ + event MilestoneDateAdded(bytes32 indexed grantId, uint256 milestoneDate); + + /** + * @dev Emitted when a milestone date is removed from the grant. + * @param grantId The unique identifier of the grant. + * @param milestoneDate The timestamp of the removed milestone. + */ + event MilestoneDateRemoved(bytes32 indexed grantId, uint256 milestoneDate); + + /** + * @dev Emitted when a disbursement is added to a milestone. + * @param grantId The unique identifier of the grant. + * @param milestoneDate The timestamp of the milestone. + * @param fundingToken The token used for the disbursement. + * @param fundingAmount The amount of the disbursement. + */ + event DisbursementAdded( + bytes32 indexed grantId, + uint256 milestoneDate, + address indexed fundingToken, + uint256 fundingAmount + ); + + /** + * @dev Emitted when a disbursement is removed from a milestone. + * @param grantId The unique identifier of the grant. + * @param milestoneDate The timestamp of the milestone. + */ + event DisbursementRemoved(bytes32 indexed grantId, uint256 milestoneDate); + + /** + * @dev Emitted when a disbursement status is updated. + * @param grantId The unique identifier of the grant. + * @param milestoneDate The timestamp of the milestone. + * @param isDisbursed Boolean indicating if the disbursement has been made. + */ + event DisbursementMade( + bytes32 indexed grantId, + uint256 milestoneDate, + bool isDisbursed + ); + + /** + * @dev Emitted when an external link is added to the grant. + * @param grantId The unique identifier of the grant. + * @param link The external URL added. + */ + event ExternalLinkAdded(bytes32 indexed grantId, string link); + + /** + * @dev Emitted when an external link is removed from the grant. + * @param grantId The unique identifier of the grant. + * @param link The external URL removed. + */ + event ExternalLinkRemoved(bytes32 indexed grantId, string link); + + /** + * @dev Registers a new grant with the provided details. `grantId` is generated by hashing the grant + * details and the current timestamp. + * + * Requirements: + * + * - The `grantManager` address must not be the zero address. + * - The `community` name must not be empty. + * - The grant must not already be registered. + * + * Emits a {GrantRegistered} event. + * + * @param id The unique identifier for the grant program. + * @param chainid The chain ID where the grant is being registered. + * @param community The name of the community or protocol issuing the grant. + * @param grantManager The address of the grant manager. + * @return The generated `grantId` as a bytes32 value. + */ + function registerGrant( + uint256 id, + uint256 chainid, + string memory community, + address grantManager + ) external returns (bytes32); + + /** + * @dev Transfers ownership of the grant to a new grant manager. + * + * Requirements: + * + * - The caller must be the current grant manager. + * - The `newGrantManager` address must not be the zero address. + * + * Emits an {OwnershipTransferred} event. + * + * @param grantId The unique identifier of the grant. + * @param newGrantManager The address of the new grant manager. + */ + function transferOwnership(bytes32 grantId, address newGrantManager) external; + + /** + * @dev Adds a new grantee to the grant. + * + * Requirements: + * + * - The caller must be the current grant manager. + * - The `grantee` address must not be the zero address. + * + * Emits a {GranteeAdded} event. + * + * @param grantId The unique identifier of the grant. + * @param grantee The address of the grantee to be added. + */ + function addGrantee(bytes32 grantId, address grantee) external; + + /** + * @dev Removes an existing grantee from the grant. + * + * Requirements: + * + * - The caller must be the current grant manager. + * - The `grantee` address must be present in the grant. + * + * Emits a {GranteeRemoved} event. + * + * @param grantId The unique identifier of the grant. + * @param grantee The address of the grantee to be removed. + */ + function removeGrantee(bytes32 grantId, address grantee) external; + + /** + * @dev Sets the start date for the grant. + * + * Requirements: + * + * - The caller must be the current grant manager. + * + * Emits a {StartDateSet} event. + * + * @param grantId The unique identifier of the grant. + * @param startDate The timestamp representing the start date. + */ + function setStartDate(bytes32 grantId, uint256 startDate) external; + + /** + * @dev Adds a new milestone date for the grant. + * + * Requirements: + * + * - The caller must be the current grant manager. + * - The milestone date must not already exist in the grant. + * + * Emits a {MilestoneDateAdded} event. + * + * @param grantId The unique identifier of the grant. + * @param milestoneDate The timestamp representing the milestone date. + */ + function addMilestoneDate(bytes32 grantId, uint256 milestoneDate) external; + + /** + * @dev Removes a milestone date from the grant. + * + * Requirements: + * + * - The caller must be the current grant manager. + * - The milestone date must exist in the grant. + * + * Emits a {MilestoneDateRemoved} event. + * + * @param grantId The unique identifier of the grant. + * @param milestoneDate The timestamp representing the milestone date to be removed. + */ + function removeMilestoneDate(bytes32 grantId, uint256 milestoneDate) external; + + /** + * @dev Ovewrites a disbursement for a specific milestone. + * + * Requirements: + * + * - The caller must be the current grant manager. + * - The milestone date must exist in the grant. + * + * Emits a {DisbursementAdded} event. + * + * @param grantId The unique identifier of the grant. + * @param milestoneDate The milestone date associated with the disbursement. + * @param fundingToken The address of the token used for funding. + * @param fundingAmount The amount of tokens to be disbursed. + */ + function addDisbursement( + bytes32 grantId, + uint256 milestoneDate, + address fundingToken, + uint256 fundingAmount + ) external; + + /** + * @dev Removes a disbursement for a specific milestone. + * + * Requirements: + * + * - The caller must be the current grant manager. + * - The milestone date must exist in the grant. + * + * Emits a {DisbursementRemoved} event. + * + * @param grantId The unique identifier of the grant. + * @param milestoneDate The milestone date associated with the disbursement. + */ + function removeDisbursement(bytes32 grantId, uint256 milestoneDate) external; + + /** + * @dev Updates the disbursement status for a specific milestone. + * + * Requirements: + * + * - The caller must be the current grant manager. + * - The milestone date must exist in the grant. + * + * Emits a {DisbursementMade} event. + * + * @param grantId The unique identifier of the grant. + * @param milestoneDate The milestone date associated with the disbursement. + * @param isDisbursed A boolean value indicating if the disbursement has been made. + */ + function setDisbursementStatus( + bytes32 grantId, + uint256 milestoneDate, + bool isDisbursed + ) external; + + /** + * @dev Adds an external link related to the grant. + * + * Requirements: + * + * - The caller must be the current grant manager. + * - The link must not be empty. + * + * Emits an {ExternalLinkAdded} event. + * + * @param grantId The unique identifier of the grant. + * @param link The external URL to be added. + */ + function addExternalLink(bytes32 grantId, string memory link) external; + + /** + * @dev Removes an external link associated with the grant. + * + * Requirements: + * + * - The caller must be the current grant manager. + * - The index must be within the bounds of the external links array. + * + * Emits an {ExternalLinkRemoved} event. + * + * @param grantId The unique identifier of the grant. + * @param index The index of the external link to be removed. + */ + function removeExternalLink(bytes32 grantId, uint256 index) external; + + /** + * @dev Retrieves details of a specific grant by its ID + * @param grantId The unique identifier of the grant + * @return The `Grant` struct containing id, chainid, and community label + */ + function getGrant(bytes32 grantId) external view returns (Grant memory); + + /** + * @dev Retrieves the current grant manager for a specific grant + * @param grantId The unique identifier of the grant + * @return The address of the grant manager + */ + function getGrantManager(bytes32 grantId) external view returns (address); + + /** + * @dev Retrieves the list of grantees associated with a specific grant + * @param grantId The unique identifier of the grant + * @return An array of addresses representing the grantees + */ + function getGrantees( + bytes32 grantId + ) external view returns (address[] memory); + + /** + * @dev Retrieves the start date and list of milestone dates for a specific grant + * @param grantId The unique identifier of the grant + * @return The start date and an array of milestone dates + */ + function getMilestonesDates( + bytes32 grantId + ) external view returns (uint256, uint256[] memory); + + /** + * @dev Retrieves the disbursement details for a specific milestone in a grant + * @param grantId The unique identifier of the grant + * @param milestoneDate The date of the milestone for which disbursement details are requested + * @return The `Disbursements` struct containing the token address, funding amount, and disbursement status + */ + function getDisbursement( + bytes32 grantId, + uint256 milestoneDate + ) external view returns (Disbursements memory); + + /** + * @dev Retrieves the list of external links associated with a specific grant + * @param grantId The unique identifier of the grant + * @return An array of strings representing the external links + */ + function getExternalLinks( + bytes32 grantId + ) external view returns (string[] memory); +} +``` + +When calling the `registerGrant` function: + +- The `grantManager` **MUST** submit a valid grantManager address that is not the zero address. +- The `community` label **MUST** be a non-empty string. +- The `grant` ID **MUST** be unique and not already registered in the system. + +When editing overall grant details: + +- The `grantManager` **MUST** be the current grant manager to make changes to the grant. + +When adding a `milestoneDate`: + +- The `milestoneDate` **MUST** not exist in the milestonesDates set. + +When editing disbursments: + +- The `milestoneDate` **MUST** be a valid milestone date associated with the grant. + +When adding `externalLinks`: + +- The string **MUST** not be empty. + + +## Rationale + +The design of this Grant Registry Contract is driven by the need for a flexible and modular system that supports a wide range of grant programs across different chains. The rationale for the key design decisions is outlined below: + +1. Separation of Fields: The division of fields into different categories, such as identification, grant data, and disbursement-related information, allows for a more efficient use of on-chain storage. Immutable fields like id, chainid, and community are kept separate from mutable fields, ensuring that core identification elements remain unchanged, while other aspects like milestones and participants can be updated throughout the grant lifecycle. + +2. Modular Disbursement Handling: Not all grant programs will choose to perform disbursements on-chain. By allowing disbursements to be managed through external links, the contract remains modular and adaptable to different use cases. Programs that prefer to handle disbursements off-chain can still use the registry for status tracking, ensuring broad applicability across different ecosystems. + +3. Dynamic Team Management: The participants structure uses EnumerableSet for grantees, allowing for team-based grants. This feature facilitates tracking of contributions and adjustments to the grant team over time, enabling more comprehensive reputation systems and transparency. + +This design aims to create a scalable, efficient system that can evolve with the needs of different grant programs, while maintaining key benefits like transparency, modularity, and low gas usage. + +## Backwards Compatibility + +No backward compatibility issues found. + +## Reference Implementation + +```solidity +// SPDX-License-Identifier: CC0-1.0 +pragma solidity ^0.8.20; + +import { IGrantRegistry } from "./IGrantRegistry.sol"; +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; + +contract GrantRegistry is IGrantRegistry { + using EnumerableSet for EnumerableSet.AddressSet; + using EnumerableSet for EnumerableSet.UintSet; + + /** + * @dev Mapping to store the details of each grant, keyed by its unique grantId. + */ + mapping(bytes32 => Grant) private _grants; + + /** + * @dev Stores information about the participants in each grant (manager and grantees), keyed by the grantId. + * This mapping allows tracking of the grant manager and the associated grantees for each grant. + */ + mapping(bytes32 => Participants) private _participants; + + /** + * @dev Stores milestone-related data for each grant, keyed by the grantId. + * This includes the start date, milestone dates, and disbursements related to each milestone. + */ + mapping(bytes32 => Milestones) private _milestones; + + /** + * @dev Stores external links related to each grant, such as proposal URLs or related documentation, keyed by grantId. + * External links provide references to off-chain information about the grant. + */ + mapping(bytes32 => string[]) private _externalLinks; + + /** + * @dev See {IGrantRegistry-registerGrant}. + */ + function registerGrant( + uint256 id, + uint256 chainid, + string memory community, + address grantManager + ) external returns (bytes32) { + bytes32 grantId = keccak256( + abi.encodePacked(id, chainid, community, block.timestamp) + ); + + if (grantManager == address(0)) revert InvalidGrantManager(); + if (bytes(community).length == 0) revert InvalidCommunityNameLength(); + if (bytes(_grants[grantId].community).length > 0) + revert GrantAlreadyRegistered(); + + _grants[grantId] = Grant(id, chainid, community); + _participants[grantId].grantManager = grantManager; + + emit GrantRegistered(grantId, id, chainid, community, grantManager); + return grantId; + } + + /** + * @dev See {IGrantRegistry-transferOwnership}. + */ + function transferOwnership( + bytes32 grantId, + address newGrantManager + ) external { + _requireManager(grantId); + if (newGrantManager == address(0)) revert InvalidGrantManager(); + _participants[grantId].grantManager = newGrantManager; + emit OwnershipTransferred(grantId, newGrantManager); + } + + /** + * @dev See {IGrantRegistry-addGrantee}. + */ + function addGrantee(bytes32 grantId, address grantee) external { + _requireManager(grantId); + if (grantee == address(0)) revert InvalidGrantManager(); + bool success = _participants[grantId].grantees.add(grantee); + if (!success) revert GranteeAlreadyAdded(); + emit GranteeAdded(grantId, grantee); + } + + /** + * @dev See {IGrantRegistry-removeGrantee}. + */ + function removeGrantee(bytes32 grantId, address grantee) external { + _requireManager(grantId); + bool success = _participants[grantId].grantees.remove(grantee); + if (!success) revert GranteeNotFound(); + emit GranteeRemoved(grantId, grantee); + } + + /** + * @dev See {IGrantRegistry-setStartDate}. + */ + function setStartDate(bytes32 grantId, uint256 startDate) external { + _requireManager(grantId); + _milestones[grantId].startDate = startDate; + emit StartDateSet(grantId, startDate); + } + + /** + * @dev See {IGrantRegistry-addMilestoneDate}. + */ + function addMilestoneDate(bytes32 grantId, uint256 milestoneDate) external { + _requireManager(grantId); + bool success = _milestones[grantId].milestonesDates.add(milestoneDate); + if (!success) revert MilestoneDateAlreadyAdded(); + emit MilestoneDateAdded(grantId, milestoneDate); + } + + /** + * @dev See {IGrantRegistry-removeMilestoneDate}. + */ + function removeMilestoneDate( + bytes32 grantId, + uint256 milestoneDate + ) external { + _requireManager(grantId); + bool success = _milestones[grantId].milestonesDates.remove(milestoneDate); + if (!success) revert MilestoneDateNotFound(); + emit MilestoneDateRemoved(grantId, milestoneDate); + } + + /** + * @dev See {IGrantRegistry-addDisbursement}. + */ + function addDisbursement( + bytes32 grantId, + uint256 milestoneDate, + address fundingToken, + uint256 fundingAmount + ) external { + _requireManager(grantId); + _requireMilestoneDate(grantId, milestoneDate); + _milestones[grantId].disbursements[milestoneDate] = Disbursements( + fundingToken, + fundingAmount, + false + ); + emit DisbursementAdded(grantId, milestoneDate, fundingToken, fundingAmount); + } + + /** + * @dev See {IGrantRegistry-removeDisbursement}. + */ + function removeDisbursement(bytes32 grantId, uint256 milestoneDate) external { + _requireManager(grantId); + _requireMilestoneDate(grantId, milestoneDate); + delete _milestones[grantId].disbursements[milestoneDate]; + emit DisbursementRemoved(grantId, milestoneDate); + } + + /** + * @dev See {IGrantRegistry-setDisbursementStatus}. + */ + function setDisbursementStatus( + bytes32 grantId, + uint256 milestoneDate, + bool isDisbursed + ) external { + _requireManager(grantId); + _requireMilestoneDate(grantId, milestoneDate); + _milestones[grantId].disbursements[milestoneDate].isDisbursed = isDisbursed; + emit DisbursementMade(grantId, milestoneDate, isDisbursed); + } + + /** + * @dev See {IGrantRegistry-addExternalLink}. + */ + function addExternalLink(bytes32 grantId, string memory link) external { + _requireManager(grantId); + if (bytes(link).length == 0) revert InvalidExternalLink(); + _externalLinks[grantId].push(link); + emit ExternalLinkAdded(grantId, link); + } + + /** + * @dev See {IGrantRegistry-removeExternalLink}. + */ + function removeExternalLink(bytes32 grantId, uint256 index) external { + _requireManager(grantId); + if (index >= _externalLinks[grantId].length) revert InvalidIndex(); + string memory link = _externalLinks[grantId][index]; + _externalLinks[grantId][index] = _externalLinks[grantId][ + _externalLinks[grantId].length - 1 + ]; + _externalLinks[grantId].pop(); + emit ExternalLinkRemoved(grantId, link); + } + + /** + * @dev Ensures that the caller is the grant manager for the given grantId. + * Reverts with `InvalidGrantManager` if the caller is not the grant manager. + * @param grantId The unique identifier of the grant being checked. + */ + function _requireManager(bytes32 grantId) internal view { + if (msg.sender != _participants[grantId].grantManager) + revert InvalidGrantManager(); + } + + /** + * @dev Ensures that the milestone date is present in the grant. + * Reverts with `MilestoneDateNotFound` if the milestone date is not present. + * @param grantId The unique identifier of the grant being checked. + * @param milestoneDate The milestone date being checked. + */ + function _requireMilestoneDate( + bytes32 grantId, + uint256 milestoneDate + ) internal view { + if (!_milestones[grantId].milestonesDates.contains(milestoneDate)) + revert MilestoneDateNotFound(); + } + + /** + * @dev See {IGrantRegistry-getGrant}. + */ + function getGrant(bytes32 grantId) external view returns (Grant memory) { + return _grants[grantId]; + } + + /** + * @dev See {IGrantRegistry-getGrantManager}. + */ + function getGrantManager(bytes32 grantId) external view returns (address) { + return _participants[grantId].grantManager; + } + + /** + * @dev See {IGrantRegistry-getGrantees}. + */ + function getGrantees( + bytes32 grantId + ) external view returns (address[] memory) { + return _participants[grantId].grantees.values(); + } + + /** + * @dev See {IGrantRegistry-getMilestonesDates}. + */ + function getMilestonesDates( + bytes32 grantId + ) external view returns (uint256, uint256[] memory) { + return ( + _milestones[grantId].startDate, + _milestones[grantId].milestonesDates.values() + ); + } + + /** + * @dev See {IGrantRegistry-getDisbursement}. + */ + function getDisbursement( + bytes32 grantId, + uint256 milestoneDate + ) external view returns (Disbursements memory) { + return _milestones[grantId].disbursements[milestoneDate]; + } + + /** + * @dev See {IGrantRegistry-getExternalLinks}. + */ + function getExternalLinks( + bytes32 grantId + ) external view returns (string[] memory) { + return _externalLinks[grantId]; + } +} +``` + +Key considerations for this implementation: + +1. Gas Optimization: `grantId` utilizes immutable identification fields to minimize large gas consumption. This ensures that essential information is used with keccak256 efficiently, while the mutable data can be submitted or modified later as the project evolves without affecting the identification method. + +2. Use of EnumerableSet: By leveraging EnumerableSet for managing participants and milestone dates, the contract allows for dynamic updates, such as team composition changes or new milestones. This approach offers flexibility without sacrificing the ability to efficiently track changes. + +## Security Considerations + +No security concerns were found. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From 37f891c0a6c3c977ed0ae70b4085f84ec34db878 Mon Sep 17 00:00:00 2001 From: Ignacio Ceaglio Date: Tue, 29 Oct 2024 16:15:59 +0100 Subject: [PATCH 38/46] Add ERC: Transparent Financial Statements Merged by EIP-Bot. --- ERCS/erc-7776.md | 572 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 572 insertions(+) create mode 100644 ERCS/erc-7776.md diff --git a/ERCS/erc-7776.md b/ERCS/erc-7776.md new file mode 100644 index 0000000000..4055653954 --- /dev/null +++ b/ERCS/erc-7776.md @@ -0,0 +1,572 @@ +--- +eip: 7776 +title: Transparent Financial Statements +description: Open Transparent Financial Data such as Revenue, Costs of Goods Sold, Operating Expenses, EBITDA and Earnings Per Share for all Investors. +author: Ignacio Ceaglio (@Nachoxt17) +discussions-to: https://ethereum-magicians.org/t/erc-xxxx-transparent-financial-statements/21191 +status: Draft +type: Standards Track +category: ERC +created: 2024-09-20 +requires: 20 +--- + +## Abstract + +This proposal defines a standard API that enables EVM Blockchain-based companies (or also called "protocols") to publish their financial information, specifically Income Statements and Balance Sheets, on- +chain in a transparent and accessible manner through solidity smart contracts. This standard aims to emulate the reporting structure used by publicly traded companies in traditional stocks markets, like +the SEC 10-Q filings. The financial statements include key information, namely as Revenue, Cost of Goods Sold, Operating Expenses, Operating Income, Earnings before Interest, Taxes, Depreciation, and +Amortization (EBITDA) and +Earnings Per Share-Token (EPS), allowing investors to assess the financial health of blockchain-based companies in a standardized, transparent, clear and reliable format. + +## Motivation + +The motivation of this ERC is to bring seriousness to the cryptocurrencies investments market. Currently, the situation is as follows: + +The current state of token investment analysis is opaque, with most information presented in an abstract and non-quantitative form. This standard API ensures a consistent and reliable way for investors to +evaluate blockchain projects based on real financial data published directly on-chain, not just speculative promises. This will establish a greater +trust in the cryptocurrency markets and align token analysis with the standards of traditional equity markets. + +Most [ERC-20](./eip-20.md) Tokens representing EVM Blockchain-based companies (or also called "protocols"), DO NOT work the same way as a publicly traded stock that represents a share of ownership of the +equity of that such company (so the user who buys a protocol's ERC-20, is also now a share-holder and co-owner of the business, its profits and/or its dividends), but rather function as "commodities" such +as oil; they are consumable items created by said EVM Blockchain-based company (or "protocol") to be spent in their platform. They are publicly traded and advertised to be representing the underlying +protocol like a share, working in practice the same way as a commodity and without any public, transparent and _Clear_ Financial Information as publicly traded stocks have. + +Added to that, most token research analysis reports that can be currently found on the internet are informal Substack or Twitter posts, with lots of abstract explanations about the features of the said +protocol to invest in, that lack of transparent financial numbers and factual financial information, that are made by anonymous users without real exposed reputations to affect. + +This ERC will improve that by giving users and investors transparent, clear and factual financial information to work with when analyzing as a potential investment the such +EVM Blockchain-based company that implements this ERC in their solidity smart contracts, and that will generate trust, transparency and seriousness in the cryptocurrencies investments market long term. + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in +RFC 2119 and RFC 8174. + +All Transparent Financial Statements Standard implementations MUST implement ERC-20 to represent shares, and the financial numbers such as Revenue, Costs of Goods Sold, Operating Expenses, Operating +Income, EBITDA, Other Income and Expenses, Net Income and Earnings Per Share MUST be displayed in the value of the protocol's stablecoin of choice. + +All Transparent Financial Statements MUST implement ERC-20's optional metadata extensions. +The `name` and `symbol` functions SHOULD reflect the underlying token's `name` and `symbol` in some way. + +All methods MUST be of visibility `external`. + +All methods MUST return their financial numbers valued in the provided `stablecoin`. + +If the contract owner uses data or methods from other owned smart contracts external to their smart contract implementation of this standard, those smart contracts MUST be verified in the correspondent +blockchain explorer and of open and visible source code. + +_Timestamp Constraint_: For all methods, `startTimestamp` MUST be less than or equal to `endTimestamp`. If `startTimestamp` is equal to `endTimestamp`, the method returns a balance sheet snapshot. If +`startTimestamp` is less than `endTimestamp`, the method returns an income statement for that period. + +_Output Structs_: Instead of a single `uint256` value, each method returns a `struct` with one or _OPTIONAL_ more `uint256` entries to allow for detailed financial data, each one with their own customized +entry `name`. + +### Definitions: + +- Currency: The individual stablecoin used to value the publicly displayed financial numbers. +- Revenue: Total earnings from selling products or services before expenses. +- Cost of Goods Sold (COGS): Direct costs for producing goods/services, including labor and materials. +- Operating Expenses: Expenses like Selling, General, and Administrative, Research and Development, and other operational costs. +- Operating Income: Revenue minus operating expenses. +- EBITDA: Earnings Before Interest, Taxes, Depreciation, and Amortization. +- Other Income and Expenses: Non-operating income, such as interest, investment gains or losses. +- Net Income: Profit after all expenses, taxes, and deductions. +- EPS: Earnings per Share Token (ERC-20), showing profit allocated per share. + +### Methods + +#### `stablecoinAddress` + +Returns the `address` of the individual stablecoin used to value the publicly displayed financial numbers. + +```yaml +- name: stablecoinAddress + type: function + visibility: external + stateMutability: view + inputs: + /none/ + outputs: + - name: currencyAddress + type: address + +``` + +#### `revenue` + +Returns total revenue generated by the protocol within a time period. + +```yaml +- name: revenue + type: function + visibility: external + stateMutability: view + inputs: + - name: startTimestamp + type: uint256 + - name: endTimestamp + type: uint256 + outputs: + - name: RevenueStruct + type: struct + fields: + - name: grossRevenue + type: uint256 + - name: optionalAdditionalRevenueDetail1 + type: uint256 + - name: optionalAdditionalRevenueDetailN + type: uint256 + +``` + +#### `cogs` + +Returns the cost of goods sold within a specified period. + +```yaml +- name: cogs + type: function + visibility: external + stateMutability: view + inputs: + - name: startTimestamp + type: uint256 + - name: endTimestamp + type: uint256 + outputs: + - name: COGSStruct + type: struct + fields: + - name: totalCOGS + type: uint256 + - name: optionalAdditionalCOGSDetail1 + type: uint256 + - name: optionalAdditionalCOGSDetailN + type: uint256 + +``` + +#### `operatingExpenses` + +Returns the total operating expenses within a specified period. + +```yaml +- name: operatingExpenses + type: function + visibility: external + stateMutability: view + inputs: + - name: startTimestamp + type: uint256 + - name: endTimestamp + type: uint256 + outputs: + - name: OperatingExpensesStruct + type: struct + fields: + - name: totalOperatingExpenses + type: uint256 + - name: optionalAdditionalExpenseDetail1 + type: uint256 + - name: optionalAdditionalExpenseDetailN + type: uint256 + +``` + +#### `operatingIncome` + +Returns operating income for the specified period (Revenue - COGS - Operating Expenses). + +```yaml +- name: operatingIncome + type: function + visibility: external + stateMutability: view + inputs: + - name: startTimestamp + type: uint256 + - name: endTimestamp + type: uint256 + outputs: + - name: OperatingIncomeStruct + type: struct + fields: + - name: totalOperatingIncome + type: uint256 + - name: optionalAdditionalIncomeDetail1 + type: uint256 + - name: optionalAdditionalIncomeDetailN + type: uint256 + +``` + +#### `ebitda` + +Returns EBITDA for the given period. + +```yaml +- name: ebitda + type: function + visibility: external + stateMutability: view + inputs: + - name: startTimestamp + type: uint256 + - name: endTimestamp + type: uint256 + outputs: + - name: EBITDAstruct + type: struct + fields: + - name: totalEBITDA + type: uint256 + - name: optionalAdditionalEBITDADetail1 + type: uint256 + - name: optionalAdditionalEBITDADetailN + type: uint256 + +``` + +#### `otherIncomeExpenses` + +Returns non-operating income and expenses, such as interest and investment gains or losses, for the specified period. + +```yaml +- name: otherIncomeExpenses + type: function + visibility: external + stateMutability: view + inputs: + - name: startTimestamp + type: uint256 + - name: endTimestamp + type: uint256 + outputs: + - name: OtherIncomeExpensesStruct + type: struct + fields: + - name: totalOtherIncome + type: uint256 + - name: totalOtherExpenses + type: uint256 + - name: totalOtherIncomeDetail1 + type: uint256 + - name: totalOtherExpensesDetail1 + type: uint256 + - name: totalOtherIncomeDetailN + type: uint256 + - name: totalOtherExpensesDetailN + type: uint256 + +``` + +#### `netIncome` + +Returns net income for the period (Operating Income + Other Income/Expenses - Taxes - Depreciation). + +```yaml +- name: netIncome + type: function + visibility: external + stateMutability: view + inputs: + - name: startTimestamp + type: uint256 + - name: endTimestamp + type: uint256 + outputs: + - name: NetIncomeStruct + type: struct + fields: + - name: totalNetIncome + type: uint256 + - name: optionalAdditionalNetIncomeDetail1 + type: uint256 + - name: optionalAdditionalNetIncomeDetailN + type: uint256 + +``` + +#### `earningsPerShare` + +Returns Earnings Per Share Token (EPS) for the period. + +```yaml +- name: earningsPerShare + type: function + visibility: external + stateMutability: view + inputs: + - name: startTimestamp + type: uint256 + - name: endTimestamp + type: uint256 + outputs: + - name: EPSstruct + type: struct + fields: + - name: basicEPS + type: uint256 + - name: dilutedEPS + type: uint256 + - name: EPSDetail1 + type: uint256 + - name: EPSDetailN + type: uint256 + +``` + +#### `fullFinancialReport` + +Returns a comprehensive struct that includes all the prior financial details of the protocol combined: Revenue, COGS, Operating Expenses, Operating Income, EBITDA, Other Incomes and Expenses, Net income, +and EPS into a unified `Struct`. + +```yaml +- name: fullFinancialReport + type: function + visibility: external + stateMutability: view + inputs: + - name: startTimestamp + type: uint256 + - name: endTimestamp + type: uint256 + outputs: + - name: FullFinancialsStruct + type: struct + fields: + - name: RevenueStruct + type: struct + - name: COGSStruct + type: struct + - name: OperatingExpensesStruct + type: struct + - name: OperatingIncomeStruct + type: struct + - name: EBITDAstruct + type: struct + - name: OtherIncomeExpensesStruct + type: struct + - name: NetIncomeStruct + type: struct + - name: EPSstruct + type: struct + +``` + +## Rationale + +ERC-20 is enforced because implementation details like Earnings Per Token calculation directly carry over to the accounting. This standardization makes the Transparent Financial Statements compatible with +all ERC-20 use cases. + +This implementation enables the protocol to share their financial information both as their latest updated Balance Sheet (if the user chooses to just see a current snapshot of +the financial state of the company) and as an Income Statement (if the user chooses to see the evolution of the financial state of the company between two different block +timestamps) and also is thought to interact with other separated Smart Contracts of the same protocol from which the financial information will be sent. + +## Backwards Compatibility + +Transparent Financial Statements Standard is fully backward compatible with the ERC-20 standard and has no known compatibility issues with other standards. + +## Reference Implementation + + +_NOTE: This Reference Implementation is a placeholder. It will be improved in the future from the feedback received._ + + +```solidity +// SPDX-License-Identifier: CC0-1.0 +pragma solidity 0.8.27; + +interface IERC20 { + function name() external view returns (string memory); + function symbol() external view returns (string memory); +} + +contract TransparentFinancialStatements { + + address public stablecoin; + + struct RevenueStruct { + uint256 grossRevenue; + uint256 optionalAdditionalRevenueDetail1; + uint256 optionalAdditionalRevenueDetailN; + } + + struct COGSStruct { + uint256 totalCOGS; + uint256 optionalAdditionalCOGSDetail1; + uint256 optionalAdditionalCOGSDetailN; + } + + struct OperatingExpensesStruct { + uint256 totalOperatingExpenses; + uint256 optionalAdditionalExpenseDetail1; + uint256 optionalAdditionalExpenseDetailN; + } + + struct OperatingIncomeStruct { + uint256 totalOperatingIncome; + uint256 optionalAdditionalIncomeDetail1; + uint256 optionalAdditionalIncomeDetailN; + } + + struct EBITDAstruct { + uint256 totalEBITDA; + uint256 optionalAdditionalEBITDADetail1; + uint256 optionalAdditionalEBITDADetailN; + } + + struct OtherIncomeExpensesStruct { + uint256 totalOtherIncome; + uint256 totalOtherExpenses; + uint256 totalOtherIncomeDetail1; + uint256 totalOtherExpensesDetail1; + uint256 totalOtherIncomeDetailN; + uint256 totalOtherExpensesDetailN; + } + + struct NetIncomeStruct { + uint256 totalNetIncome; + uint256 optionalAdditionalNetIncomeDetail1; + uint256 optionalAdditionalNetIncomeDetailN; + } + + struct EPSstruct { + uint256 basicEPS; + uint256 dilutedEPS; + uint256 EPSDetail1; + uint256 EPSDetailN; + } + + struct FullFinancialsStruct { + RevenueStruct revenue; + COGSStruct cogs; + OperatingExpensesStruct operatingExpenses; + OperatingIncomeStruct operatingIncome; + EBITDAstruct ebitda; + OtherIncomeExpensesStruct otherIncomeExpenses; + NetIncomeStruct netIncome; + EPSstruct eps; + } + + constructor(address _stablecoin) { + stablecoin = _stablecoin; + } + + function currency() public view returns (address) { + return stablecoin; + } + + function revenue(uint256 startTimestamp, uint256 endTimestamp) + public + view + returns (RevenueStruct memory) + { + require(startTimestamp <= endTimestamp, "Invalid timestamps"); + // Logic to calculate and return revenue details + return RevenueStruct(1000, 500, 100); // Example values + } + + function cogs(uint256 startTimestamp, uint256 endTimestamp) + public + view + returns (COGSStruct memory) + { + require(startTimestamp <= endTimestamp, "Invalid timestamps"); + // Logic to calculate and return COGS details + return COGSStruct(400, 150, 50); // Example values + } + + function operatingExpenses(uint256 startTimestamp, uint256 endTimestamp) + public + view + returns (OperatingExpensesStruct memory) + { + require(startTimestamp <= endTimestamp, "Invalid timestamps"); + // Logic to calculate and return operating expenses details + return OperatingExpensesStruct(300, 100, 50); // Example values + } + + function operatingIncome(uint256 startTimestamp, uint256 endTimestamp) + public + view + returns (OperatingIncomeStruct memory) + { + require(startTimestamp <= endTimestamp, "Invalid timestamps"); + // Logic to calculate and return operating income details + return OperatingIncomeStruct(300, 100, 50); // Example values + } + + function ebitda(uint256 startTimestamp, uint256 endTimestamp) + public + view + returns (EBITDAstruct memory) + { + require(startTimestamp <= endTimestamp, "Invalid timestamps"); + // Logic to calculate and return EBITDA details + return EBITDAstruct(700, 200, 100); // Example values + } + + function otherIncomeExpenses(uint256 startTimestamp, uint256 endTimestamp) + public + view + returns (OtherIncomeExpensesStruct memory) + { + require(startTimestamp <= endTimestamp, "Invalid timestamps"); + // Logic to calculate and return other income/expenses details + return OtherIncomeExpensesStruct(100, 50, 20, 10, 30, 20); // Example values + } + + function netIncome(uint256 startTimestamp, uint256 endTimestamp) + public + view + returns (NetIncomeStruct memory) + { + require(startTimestamp <= endTimestamp, "Invalid timestamps"); + // Logic to calculate and return net income details + return NetIncomeStruct(600, 200, 100); // Example values + } + + function earningsPerShare(uint256 startTimestamp, uint256 endTimestamp) + public + view + returns (EPSstruct memory) + { + require(startTimestamp <= endTimestamp, "Invalid timestamps"); + // Logic to calculate and return EPS details + return EPSstruct(10, 8, 2, 1); // Example values + } + + function fullFinancialReport(uint256 startTimestamp, uint256 endTimestamp) + public + view + returns (FullFinancialsStruct memory) + { + require(startTimestamp <= endTimestamp, "Invalid timestamps"); + // Logic to calculate and return all financial details + return FullFinancialsStruct( + revenue(startTimestamp, endTimestamp), + cogs(startTimestamp, endTimestamp), + operatingExpenses(startTimestamp, endTimestamp), + operatingIncome(startTimestamp, endTimestamp), + ebitda(startTimestamp, endTimestamp), + otherIncomeExpenses(startTimestamp, endTimestamp), + netIncome(startTimestamp, endTimestamp), + earningsPerShare(startTimestamp, endTimestamp) + ); + } +} + +``` + +## Security Considerations + +This ERC involves displaying critical financial data on-chain, so special attention must be paid to ensure the accuracy and security of the data, particularly in preventing tampering or manipulation of key +financial figures. Further discussion on validation mechanisms and audits for the smart contracts containing financial data is necessary. + +Needs discussion. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From 88350ff7a6591839ddab898316b7768946fcaa21 Mon Sep 17 00:00:00 2001 From: Alex Forshtat Date: Wed, 30 Oct 2024 19:00:52 +0100 Subject: [PATCH 39/46] Update ERC-4337: Extract aggregation to a separate ERC Merged by EIP-Bot. --- ERCS/erc-4337.md | 90 +++++++----------------------------------------- 1 file changed, 13 insertions(+), 77 deletions(-) diff --git a/ERCS/erc-4337.md b/ERCS/erc-4337.md index 72c0c4ddf2..c4c9646d5c 100644 --- a/ERCS/erc-4337.md +++ b/ERCS/erc-4337.md @@ -31,7 +31,6 @@ This proposal takes a different approach, avoiding any adjustments to the consen * Privacy-preserving applications * Atomic multi-operations (similar goal to [EIP-3074]) * Pay tx fees with [ERC-20](./eip-20.md) tokens, allow developers to pay fees for their users, and [EIP-3074]-like **sponsored transaction** use cases more generally - * Support aggregated signature (e.g. BLS) ## Specification @@ -52,7 +51,6 @@ This proposal takes a different approach, avoiding any adjustments to the consen other kind of PBS (proposer-builder separation) * The `bundler` can also rely on an experimental `eth_sendRawTransactionConditional` RPC API if it is available. * **Paymaster** - a helper contract that agrees to pay for the transaction, instead of the sender itself. -* **Aggregator** - a helper contract trusted by accounts to validate an aggregated signature. Bundlers/Clients whitelist the supported aggregators. ### UserOperation @@ -102,17 +100,6 @@ The core interface of the entry point contract is as follows: ```solidity function handleOps(PackedUserOperation[] calldata ops, address payable beneficiary); - -function handleAggregatedOps( - UserOpsPerAggregator[] calldata opsPerAggregator, - address payable beneficiary -); - -struct UserOpsPerAggregator { - PackedUserOperation[] userOps; - IAggregator aggregator; - bytes signature; -} ``` ### Account Contract Interface @@ -132,18 +119,15 @@ The `userOpHash` is a hash over the userOp (except signature), entryPoint and ch The account: * MUST validate the caller is a trusted EntryPoint -* If the account does not support signature aggregation, it MUST validate that the signature is a valid signature of the `userOpHash`, and +* MUST validate that the signature is a valid signature of the `userOpHash`, and SHOULD return SIG_VALIDATION_FAILED (and not revert) on signature mismatch. Any other error MUST revert. * MUST pay the entryPoint (caller) at least the "missingAccountFunds" (which might be zero, in case the current account's deposit is high enough) * The account MAY pay more than this minimum, to cover future transactions (it can always issue `withdrawTo` to retrieve it) * The return value MUST be packed of `authorizer`, `validUntil` and `validAfter` timestamps. - * authorizer - 0 for valid signature, 1 to mark signature failure. Otherwise, an address of an authorizer contract. This ERC defines a "signature aggregator" as an authorizer. + * authorizer - 0 for valid signature, 1 to mark signature failure. Otherwise, an address of an authorizer contract, as defined in [ERC-7766](./eip-7766.md). * `validUntil` is 6-byte timestamp value, or zero for "infinite". The UserOp is valid only up to this time. * `validAfter` is 6-byte timestamp. The UserOp is valid only after this time. -An account that works with aggregated signature, should return its signature aggregator address in the "sigAuthorizer" return value of validateUserOp. -It MAY ignore the signature field. - The account MAY implement the interface `IAccountExecute` ```solidity @@ -222,11 +206,8 @@ this bundler is supposed to track the `key` and `sequence` pair of the UserOpera ### Required entry point contract functionality -There are 2 separate entry point methods: `handleOps` and `handleAggregatedOps` +The entry point method is `handleOps`, which handles an array of userOps -* `handleOps` handles userOps of accounts that don't require any signature aggregator. -* `handleAggregatedOps` can handle a batch that contains userOps of multiple aggregators (and also requests without any aggregator) -* `handleAggregatedOps` performs the same logic below as `handleOps`, but it must transfer the correct aggregator to each userOp, and also must call `validateSignatures` on each aggregator before doing all the per-account validation. The entry point's `handleOps` function must perform the following steps (we first describe the simpler non-paymaster case). It must make two loops, the **verification loop** and the **execution loop**. In the verification loop, the `handleOps` call must perform the following steps for each `UserOperation`: * **Create the account if it does not yet exist**, using the initcode provided in the `UserOperation`. If the account does not exist, _and_ the initcode is empty, or does not deploy a contract at the "sender" address, the call must fail. @@ -322,33 +303,6 @@ When a client receives a `UserOperation`, it must first run some basic sanity ch If the `UserOperation` object passes these sanity checks, the client must next run the first op simulation, and if the simulation succeeds, the client must add the op to the pool. A second simulation must also happen during bundling to make sure the UserOperation is still valid. -### Using Signature Aggregator - -A signature aggregator exposes the following interface - -```solidity -interface IAggregator { - - function validateUserOpSignature(PackedUserOperation calldata userOp) - external view returns (bytes memory sigForUserOp); - - function aggregateSignatures(PackedUserOperation[] calldata userOps) external view returns (bytes memory aggregatesSignature); - - function validateSignatures(PackedUserOperation[] calldata userOps, bytes calldata signature) view external; -} -``` - -* An account signifies it uses signature aggregation returning its address from `validateUserOp`. -* During `simulateValidation`, this aggregator is returned to the bundler as part of the `aggregatorInfo` struct. -* The bundler should first accept the aggregator (aggregators must be staked. bundler should verify it is not throttled/banned) -* To accept the UserOp, the bundler must call **validateUserOpSignature()** to validate the userOp's signature. - This method returned an alternate signature (usually empty) that should be used during bundling. -* The bundler MUST call `validateUserOp` a second time on the account with the UserOperation using that returned signature, and make sure it returns the same value. -* **aggregateSignatures()** must aggregate all UserOp signatures into a single value. -* Note that the above methods are helper methods for the bundler. The bundler MAY use a native library to perform the same validation and aggregation logic. -* **validateSignatures()** MUST validate the aggregated signature matches for all UserOperations in the array, and revert otherwise. - This method is called on-chain by `handleOps()` - ### Simulation #### Simulation Rationale @@ -357,7 +311,7 @@ To add a UserOperation into the mempool (and later to add it into a bundle) we n In addition, we need to verify that the same will hold true when executed on-chain. For this purpose, a UserOperation is not allowed to access any information that might change between simulation and execution, such as current block time, number, hash etc. In addition, a UserOperation is only allowed to access data related to this sender address: Multiple UserOperations should not access the same storage, so it is impossible to invalidate a large number of UserOperations with a single state change. -There are 3 special contracts that interact with the account: the factory (initCode) that deploys the contract, the paymaster that can pay for the gas, and a signature aggregator (described later) +There are 2 special entity contracts that interact with the account: the factory (initCode) that deploys the contract, and the paymaster that can pay for the gas. Each of these contracts is also restricted in its storage access, to make sure UserOperation validations are isolated. #### Simulation Specification: @@ -390,19 +344,15 @@ struct ReturnInfo { bytes paymasterContext; } -struct AggregatorStakeInfo { - address aggregator; - StakeInfo stakeInfo; -} - struct StakeInfo { uint256 stake; uint256 unstakeDelaySec; } - ``` +The `AggregatorStakeInfo` structure is further defined in [ERC-7766](./eip-7766.md). + This method returns `ValidationResult` or revert on validation failure. The node should drop the UserOperation if the simulation fails (either by revert or by "signature failure") @@ -413,8 +363,7 @@ The simulated call performs the full validation, by calling: 3. if specified a paymaster: `paymaster.validatePaymasterUserOp`. The simulateValidation should validate the return value (validationData) returned by the account's `validateUserOp` and paymaster's `validatePaymasterUserOp`. -The account MAY return an aggregator. See [Using Signature Aggregator](#using-signature-aggregator) -The paymaster MUST return either "0" (success) or SIG_VALIDATION_FAILED for aggregator, and not an address. +The paymaster MUST return either "0" (success) or SIG_VALIDATION_FAILED. Either return value may contain a "validAfter" and "validUntil" timestamps, which is the time-range that this UserOperation is valid on-chain. A node MAY drop a UserOperation if it expires too soon (e.g. wouldn't make it to the next block) by either the account or paymaster. If the `ValidationResult` includes `sigFail`, the client SHOULD drop the `UserOperation`. @@ -424,8 +373,8 @@ For the complete procedure see [ERC-7562](./eip-7562.md) ### Alternative Mempools -The simulation rules above are strict and prevent the ability of paymasters and signature aggregators to grief the system. -However, there might be use cases where specific paymasters (and signature aggregators) can be validated +The simulation rules above are strict and prevent the ability of paymasters to grief the system. +However, there might be use cases where specific paymasters can be validated (through manual auditing) and verified that they cannot cause any problem, while still require relaxing of the opcode rules. A bundler cannot simply "whitelist" a request from a specific paymaster: if that paymaster is not accepted by all bundlers, then its support will be sporadic at best. @@ -442,8 +391,6 @@ During bundling, the bundler should: * Exclude UserOps that access any sender address of another UserOp in the same batch. * Exclude UserOps that access any address created by another UserOp validation in the same batch (via a factory). * For each paymaster used in the batch, keep track of the balance while adding UserOps. Ensure that it has sufficient deposit to pay for all the UserOps that use it. -* Sort UserOps by aggregator, to create the lists of UserOps-per-aggregator. -* For each aggregator, run the aggregator-specific code to create aggregated signature, and update the UserOps After creating the batch, before including the transaction in a block, the bundler should: @@ -506,7 +453,7 @@ To prevent such rogue UserOperations, the bundler is required to follow a set of ### Reputation Rationale. UserOperation's storage access rules prevent them from interfering with each other. -But "global" entities - paymasters, factories and aggregators are accessed by multiple UserOperations, and thus might invalidate multiple previously valid UserOperations. +But "global" entities - paymasters and factories are accessed by multiple UserOperations, and thus might invalidate multiple previously valid UserOperations. To prevent abuse, we throttle down (or completely ban for a period of time) an entity that causes invalidation of a large number of UserOperations in the mempool. To prevent such entities from "Sybil-attack", we require them to stake with the system, and thus make such DoS attack very expensive. @@ -573,25 +520,14 @@ The result `SHOULD` be set to the **userOpHash** if and only if the request pass * If the UserOperation is valid, the client MUST return the calculated **userOpHash** for it * in case of failure, MUST return an `error` result object, with `code` and `message`. The error code and message SHOULD be set as follows: - * **code: -32602** - invalid UserOperation struct/fields - * **code: -32500** - transaction rejected by entryPoint's simulateValidation, during wallet creation or validation * The `message` field MUST be set to the FailedOp's "`AAxx`" error message from the EntryPoint - * **code: -32501** - transaction rejected by paymaster's validatePaymasterUserOp * The `message` field SHOULD be set to the revert message from the paymaster * The `data` field MUST contain a `paymaster` value - * **code: -32502** - transaction rejected because of opcode validation - * **code: -32503** - UserOperation out of time-range: either wallet or paymaster returned a time-range, and it has already expired (or will expire soon) * The `data` field SHOULD contain the `validUntil` and `validAfter` values * The `data` field SHOULD contain a `paymaster` value, if this error was triggered by the paymaster - * **code: -32504** - transaction rejected because paymaster (or signature aggregator) is throttled/banned - * The `data` field SHOULD contain a `paymaster` or `aggregator` value, depending on the failed entity - * **code: -32505** - transaction rejected because paymaster (or signature aggregator) stake or unstake-delay is too low - * The `data` field SHOULD contain a `paymaster` or `aggregator` value, depending on the failed entity + * The `data` field SHOULD contain a `paymaster` value, depending on the failed entity + * The `data` field SHOULD contain a `paymaster` value, depending on the failed entity * The `data` field SHOULD contain a `minimumStake` and `minimumUnstakeDelay` - * **code: -32506** - transaction rejected because wallet specified unsupported signature aggregator - * The `data` field SHOULD contain an `aggregator` value - * **code: -32507** - transaction rejected because of wallet signature check failed (or paymaster signature, if the paymaster uses its data as signature) - * **code: -32508** - transaction rejected because paymaster balance can't cover all pending UserOperations. ##### Example: @@ -793,7 +729,7 @@ This api must only be available in testing mode and is required by the compatibi #### * debug_bundler_clearState -Clears the bundler mempool and reputation data of paymasters/accounts/factories/aggregators. +Clears the bundler mempool and reputation data of paymasters/accounts/factories. ```json= # Request From c64bce3103580f7d839890b191b66f3208a43c06 Mon Sep 17 00:00:00 2001 From: Matt Rice Date: Wed, 30 Oct 2024 18:29:55 -0400 Subject: [PATCH 40/46] Update ERC-7683: Extending the standard Merged by EIP-Bot. --- ERCS/erc-7683.md | 332 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 261 insertions(+), 71 deletions(-) diff --git a/ERCS/erc-7683.md b/ERCS/erc-7683.md index 2d8dbaf75f..ef27ce5ef3 100644 --- a/ERCS/erc-7683.md +++ b/ERCS/erc-7683.md @@ -12,7 +12,7 @@ created: 2024-04-11 ## Abstract -The following standard allows for the implementation of a standard API for cross-chain trade execution systems. This standard provides a generic `CrossChainOrder` struct, as well as a standard `ISettlementContract` smart contract interface. +The following standard allows for the implementation of a standard API for cross-chain value-transfer systems. This standard provides generic order structs, as well as a standard set of settlement smart contract interfaces. ## Motivation @@ -24,28 +24,53 @@ By implementing a standard, cross-chain intents systems can interoperate and sha The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119. -### CrossChainOrder struct +### Glossary of Terms -A compliant cross-chain order type MUST be ABI decodable into the `CrossChainOrder` type. +- **Destination Chain**: the chain where the intent is executed and the user receives funds. Note: intents can involve multiple destination chains. +- **Filler**: a participant who fulfils a user intent on the destination chain(s) and receives payment as a reward. +- **Leg**: a portion of the user intent that can be executed independently from others. All legs must be executed for an intent to be considered fulfilled. +- **Origin chain**: the chain where the user sends funds. +- **Settlement System**: a system that custodies user deposits, verifies fills, and pays fillers for the purpose of faciliating intents. +- **Settler**: a contract that implements part of the settlement system on a particular chain. +- **User**: for the purposes of this document, the user is the end-user who is sending the order. + +### Order structs + +A compliant cross-chain order type MUST be ABI decodable into either `GaslessCrossChainOrder` or `OnchainCrossChainOrder` type. ```solidity -/// @title CrossChainOrder type -/// @notice Standard order struct to be signed by swappers, disseminated to fillers, and submitted to settlement contracts -struct CrossChainOrder { +/// @title GaslessCrossChainOrder CrossChainOrder type +/// @notice Standard order struct to be signed by users, disseminated to fillers, and submitted to origin settler contracts +struct GaslessCrossChainOrder { /// @dev The contract address that the order is meant to be settled by. /// Fillers send this order to this contract address on the origin chain - address settlementContract; + address originSettler; /// @dev The address of the user who is initiating the swap, /// whose input tokens will be taken and escrowed - address swapper; + address user; /// @dev Nonce to be used as replay protection for the order uint256 nonce; /// @dev The chainId of the origin chain - uint32 originChainId; - /// @dev The timestamp by which the order must be initiated - uint32 initiateDeadline; + uint256 originChainId; + /// @dev The timestamp by which the order must be opened + uint32 openDeadline; + /// @dev The timestamp by which the order must be filled on the destination chain + uint32 fillDeadline; + /// @dev Type identifier for the order data. This is an EIP-712 typehash. + bytes32 orderDataType; + /// @dev Arbitrary implementation-specific data + /// Can be used to define tokens, amounts, destination chains, fees, settlement parameters, + /// or any other order-type specific information + bytes orderData; +} + +/// @title OnchainCrossChainOrder CrossChainOrder type +/// @notice Standard order struct for user-opened orders, where the user is the msg.sender. +struct OnchainCrossChainOrder { /// @dev The timestamp by which the order must be filled on the destination chain uint32 fillDeadline; + /// @dev Type identifier for the order data. This is an EIP-712 typehash. + bytes32 orderDataType; /// @dev Arbitrary implementation-specific data /// Can be used to define tokens, amounts, destination chains, fees, settlement parameters, /// or any other order-type specific information @@ -53,125 +78,290 @@ struct CrossChainOrder { } ``` -Cross-chain execution systems implementing this standard SHOULD create a custom sub-type that can be parsed from the arbitrary `orderData` field. This may include information such as the tokens involved in the swap, the destination chain IDs, fulfillment constraints or settlement oracles. +Cross-chain execution systems implementing this standard SHOULD use a sub-type that can be parsed from the arbitrary `orderData` field. This may include information such as the tokens involved in the transfer, the destination chain IDs, fulfillment constraints or settlement oracles. + +All sub-types SHOULD be registered in a subtypes repository to encourage sharing of sub-types based on their functionality. See the examples section for an example of how sub-types can be used to support behavior like executing calldata on a target contract of the user's choice on the destination chain. ### ResolvedCrossChainOrder struct -A compliant cross-chain order type MUST be convertible into the `ResolvedCrossChainOrder` struct. +A compliant cross-chain order type MUST be convertible into the `ResolvedCrossChainOrder` struct. This means that the `orderData` must be decoded into the information needed to populate the `ResolvedCrossChainOrder` struct. Additionally, `orderData` SHOULD be decodable into a sub-type, which can be used for further functionality such as cross-chain calldata execution (see the examples section for an example of this). It is the responsibility of the `user` and the `filler` to ensure that the `originSettler` supports their order's contained sub-type. ```solidity /// @title ResolvedCrossChainOrder type -/// @notice An implementation-generic representation of an order +/// @notice An implementation-generic representation of an order intended for filler consumption /// @dev Defines all requirements for filling an order by unbundling the implementation-specific orderData. /// @dev Intended to improve integration generalization by allowing fillers to compute the exact input and output information of any order struct ResolvedCrossChainOrder { - /// @dev The contract address that the order is meant to be settled by. - address settlementContract; - /// @dev The address of the user who is initiating the swap - address swapper; - /// @dev Nonce to be used as replay protection for the order - uint256 nonce; + /// @dev The address of the user who is initiating the transfer + address user; /// @dev The chainId of the origin chain - uint32 originChainId; - /// @dev The timestamp by which the order must be initiated - uint32 initiateDeadline; + uint256 originChainId; + /// @dev The timestamp by which the order must be opened + uint32 openDeadline; /// @dev The timestamp by which the order must be filled on the destination chain(s) uint32 fillDeadline; - - /// @dev The inputs to be taken from the swapper as part of order initiation - Input[] swapperInputs; - /// @dev The outputs to be given to the swapper as part of order fulfillment - Output[] swapperOutputs; - /// @dev The outputs to be given to the filler as part of order settlement - Output[] fillerOutputs; -} - -/// @notice Tokens sent by the swapper as inputs to the order -struct Input { - /// @dev The address of the ERC20 token on the origin chain - address token; - /// @dev The amount of the token to be sent - uint256 amount; + /// @dev The unique identifier for this order within this settlement system + bytes32 orderId; + + /// @dev The max outputs that the filler will send. It's possible the actual amount depends on the state of the destination + /// chain (destination dutch auction, for instance), so these outputs should be considered a cap on filler liabilities. + Output[] maxSpent; + /// @dev The minimum outputs that must to be given to the filler as part of order settlement. Similar to maxSpent, it's possible + /// that special order types may not be able to guarantee the exact amount at open time, so this should be considered + /// a floor on filler receipts. + Output[] minReceived; + /// @dev Each instruction in this array is parameterizes a single leg of the fill. This provides the filler with the information + /// necessary to perform the fill on the destination(s). + FillInstruction[] fillInstructions; } /// @notice Tokens that must be receive for a valid order fulfillment struct Output { /// @dev The address of the ERC20 token on the destination chain /// @dev address(0) used as a sentinel for the native token - address token; + bytes32 token; /// @dev The amount of the token to be sent uint256 amount; /// @dev The address to receive the output tokens - address recipient; + bytes32 recipient; /// @dev The destination chain for this output - uint32 chainId; + uint256 chainId; } +/// @title FillInstruction type +/// @notice Instructions to parameterize each leg of the fill +/// @dev Provides all the origin-generated information required to produce a valid fill leg +struct FillInstruction { + /// @dev The contract address that the order is meant to be settled by + uint64 destinationChainId; + /// @dev The contract address that the order is meant to be filled on + bytes32 destinationSettler; + /// @dev The data generated on the origin chain needed by the destinationSettler to process the fill + bytes originData; +} ``` -### ISettlementContract interface +### Open event -A compliant settlement contract implementation MUST implement the `ISettlementContract` interface: +A compliant `Open` event MUST adhere to the following abi: ```solidity -/// @title ISettlementContract -/// @notice Standard interface for settlement contracts -interface ISettlementContract { - /// @notice Initiates the settlement of a cross-chain order - /// @dev To be called by the filler - /// @param order The CrossChainOrder definition - /// @param signature The swapper's signature over the order - /// @param fillerData Any filler-defined data required by the settler - function initiate(CrossChainOrder order, bytes signature, bytes fillerData) external; - - /// @notice Resolves a specific CrossChainOrder into a generic ResolvedCrossChainOrder +/// @notice Signals that an order has been opened +/// @param orderId a unique order identifier within this settlement system +/// @param resolvedOrder resolved order that would be returned by resolve if called instead of Open +event Open(bytes32 indexed orderId, ResolvedCrossChainOrder resolvedOrder); +``` + +### Settlement interfaces + +A compliant origin settler contract implementation MUST implement the `IOriginSettler` interface: + +```solidity +/// @title IOriginSettler +/// @notice Standard interface for settlement contracts on the origin chain +interface IOriginSettler { + /// @notice Opens a gasless cross-chain order on behalf of a user. + /// @dev To be called by the filler. + /// @dev This method must emit the Open event + /// @param order The GaslessCrossChainOrder definition + /// @param signature The user's signature over the order + /// @param originFillerData Any filler-defined data required by the settler + function openFor(GaslessCrossChainOrder calldata order, bytes calldata signature, bytes calldata originFillerData) external; + + /// @notice Opens a cross-chain order + /// @dev To be called by the user + /// @dev This method must emit the Open event + /// @param order The OnchainCrossChainOrder definition + function open(OnchainCrossChainOrder calldata order) external; + + /// @notice Resolves a specific GaslessCrossChainOrder into a generic ResolvedCrossChainOrder + /// @dev Intended to improve standardized integration of various order types and settlement contracts + /// @param order The GaslessCrossChainOrder definition + /// @param originFillerData Any filler-defined data required by the settler + /// @return ResolvedCrossChainOrder hydrated order data including the inputs and outputs of the order + function resolveFor(GaslessCrossChainOrder calldata order, bytes calldata originFillerData) external view returns (ResolvedCrossChainOrder memory); + + /// @notice Resolves a specific OnchainCrossChainOrder into a generic ResolvedCrossChainOrder /// @dev Intended to improve standardized integration of various order types and settlement contracts - /// @param order The CrossChainOrder definition - /// @param fillerData Any filler-defined data required by the settler - /// @returns ResolvedCrossChainOrder hydrated order data including the inputs and outputs of the order - function resolve(CrossChainOrder order, bytes fillerData) external view returns (ResolvedCrossChainOrder); + /// @param order The OnchainCrossChainOrder definition + /// @return ResolvedCrossChainOrder hydrated order data including the inputs and outputs of the order + function resolve(OnchainCrossChainOrder calldata order) external view returns (ResolvedCrossChainOrder memory); } ``` +A compliant destination settlement contract implementation MUST implement the `IDestinationSettler` interface: + +```solidity +/// @title IDestinationSettler +/// @notice Standard interface for settlement contracts on the destination chain +interface IDestinationSettler { + /// @notice Fills a single leg of a particular order on the destination chain + /// @param orderId Unique order identifier for this order + /// @param originData Data emitted on the origin to parameterize the fill + /// @param fillerData Data provided by the filler to inform the fill or express their preferences + function fill(bytes32 orderId, bytes calldata originData, bytes calldata fillerData) external; +} +``` + +### fillerData + +Cross-chain execution systems implementing this standard SHOULD use a sub-type that can be parsed from the arbitrary `fillerData` field. This may include information such as the desired timing or form of payment for the filler + +All sub-types SHOULD be registered in a subtypes repository to encourage sharing of sub-types based on their functionality. + ## Rationale ### Generic OrderData -A key consideration is to ensure that a broad range of cross-chain intent designs can work within the same standard. To enable this, the specification is designed around a standard cross-chain intents *flow*, while allowing for varying implementation details within that flow. +A key consideration is to ensure that a broad range of cross-chain intent designs can work within the same standard. To enable this, the specification is designed around a cross-chain intents _flow_, with two variations: gasless and onchain. -Standard cross-chain intents flow: +#### Gasless cross-chain intents flow -1. The swapper signs an off-chain message defining the parameters of their order +Origin Chain: +1. The user signs an off-chain message defining the parameters of their order 2. The order is disseminated to fillers -3. The filler initiates the trade on the origin chain -4. The filler fills the order on the destination chain -5. A cross-chain settlement process takes place to settle the order +3. The filler calls resolve to unpack the order's requirements +4. The filler opens the order on the origin chain + +Destination Chain(s): +- The filler fills each leg of the order on the destination chain(s) + +Settlement: +- A cross-chain settlement process takes place to settle the order + +#### Onchain cross-chain intents flow + +Origin Chain: +1. The caller signs a transaction calling open with their order +2. The filler retrieves the emitted event to determine requirements + +Destination Chain(s): +- The filler fills each leg of the order on the destination chain(s) + +Settlement: +- A cross-chain settlement process takes place to settle the order + +#### Customization Within this flow, implementers of the standard have design flexibility to customize behavior such as: -- Price resolution, e.g. dutch auctions or oracle-based pricing +- Price resolution, e.g. dutch auctions (on origin or destination) or oracle-based pricing - Fulfillment constraints -- Settlement procedures. +- Settlement procedures +- Ordering of the origin and destination chain actions, e.g. the fill could happen before `open` in some settlement systems The `orderData` field allows implementations to take arbitrary specifications for these behaviors while still enabling integrators to parse the primary fields of the order. This functionality also motivated the `resolve` view function and `ResolvedCrossChainOrder` type. Resolution enables integrating fillers to validate and assess orders without specific knowledge of the `orderData` field at hand. +### Emission of Fill Instructions + +An important component of the standard is creating a flexible and robust mechanism for fillers to ensure their fills are valid. For a fill to be valid, +it typically must satisfy the following constraints: + +1. It must be filled on the correct destination chain(s) +2. It must be filled on the correct destination contract +3. It must include some (not necessarily all) information from the order that the user provided on the origin chain +4. It may require some execution information from the `open` call on the origin chain (ex. dutch auctions based on open timing) + +The `FillInstruction` array in `ResolvedCrossChainOrder` is intended to ensure it's simple for the filler to meet all of these requirements by either +listening for the `Open` or by calling `resolve`. + +One may notice that the `originData` field within `FillInstruction` is completely opaque. This opaqueness allows the settler implementations to +freely customize the data they transmit. Because fillers do not need to interpret this information, the opaqueness does not result in any +additional implementation costs on fillers. + +This functionality also makes it feasible for a user, filler, or order distribution system to perform an end-to-end simulation of the order initiation +and fill to evaluate all resulting state transitions without understanding the nuances of a particular execution system. + +### Cross-compatibility + +Since this standard is intended to reduce friction for users moving value across chains, non-EVM ecosystems should not be excluded. However, attempting +to pull each non-EVM ecosystem in would dramatically increase the size and complexity of this standard, while ommitting any that come in the future. + +Instead, this standard is intended to be cross-compatible with other ecosystems. It standardizes interfaces and data types on EVM chains, but allows +for the creation of sibling standards that define compatible interfaces, data types, and flows within other ecosystems. Intents created within these +sibling standards should be able to be filled on an EVM chain and vice versa. + +To ensure this cross-compatibility, all foreign addresses use `bytes32` rather than `address` to allow for larger address identifiers. + ### Usage of Permit2 -Permit2 is not specifically required by this standard, but does provide an efficient and straightforward approach to building standard-adherent protocols. Specifically, the `witness` functions of permit2 allow swappers to both approve the token transfer *and* the order itself with a single signature. This also nicely couples the transfer of tokens with a successful initiation of the order. +Permit2 is not specifically required by this standard, but does provide an efficient and straightforward approach to building standard-adherent protocols. Specifically, the `witness` functions of permit2 allow users to both approve the token transfer _and_ the order itself with a single signature. This also nicely couples the transfer of tokens with a successful initiation of the order. -In contrast, a standard approval model would require two separate signatures - a token approval (either [ERC-2612](./eip-2612.md) or on-chain) and a signature to approve the terms of the swap. It also decouples the token approval from the swap, meaning approved tokens could potentially be taken at any time due to a buggy or untrusted settler contract. +In contrast, a standard approval model would require two separate signatures - a token approval (either [ERC-2612](./eip-2612.md) or on-chain) and a signature to approve the terms of the order. It also decouples the token approval from the order, meaning approved tokens could potentially be taken at any time due to a buggy or untrusted settler contract. When building a standard-compliant settler system around Permit2, the following considerations should be made - `nonce` in the order struct should be a permit2 nonce -- `initiateDeadline` in the order struct should be the permit2 deadline -- A full order struct including the parsed `orderData` should be used as the witness type during the permit2 call. This ensures maximum transparency to the swapper as they sign their order permit. +- `openDeadline` in the order struct should be the permit2 deadline +- A full order struct including the parsed `orderData` should be used as the witness type during the permit2 call. This ensures maximum transparency to the user as they sign their order permit. + +### Examples + +This is an example of how a 7683 cross-chain value transfer order can include instructions to the filler to execute arbitrary calldata on behalf of the recipient on the destination chain. This calldata execution is performed by the settlement contract atomically within the filler's fill() execution, so the arbitrary contract execution can take advantage of the destination chain recipient's newly transferred value. A hypothetical user in this example would select a `originSettler` that is known to support the `Message` sub-type. + +Let there be a sub-type called `Message`, which is defined by the following structs: + +```solidity +// The Message subtype allows ERC7683 intents to carry calldata that is executed on a target contract on the destination chain. The settlement contract that the filler interacts with on the destination chain will decode the message into smart contract calls and execute the calls within the filler's `fill()` transaction. + +// The Message contains calls that the user wants executed on the destination chain. +// The target is a contract on the destination chain that the settlement contract will attempt to send callData and value to. +struct Calls { + address target; + bytes callData; + uint256 value; +} + +struct Message { + Calls[] calls; +} +``` + +The `Message` sub-type is designed to be used by a 7683 user to incentivize a filler to to execute arbitrary calldata on a target destination chain contracton the user's behalf. For example, the settlement contract might decode the `orderData` containing the message information as follows: + +```solidity +function fill(bytes32 orderId, bytes calldata originData, bytes calldata fillerData) public { + ( + address user, + uint32 fillDeadline, + Output memory fillerOutput, + Message memory message + ) = abi.decode(originData); + + // ...Do some preprocessing on the parameters here to validate the order... + + // ...Execute the fill logic of the ResolvedCrossChainOrder... + + // Handle the Message subtype: + + // Revert if any of the message calls fail. + uint256 length = message.calls.length; + for (uint256 i = 0; i < length; ++i) { + Call memory call = message.calls[i]; + + // If we are calling an EOA with calldata, assume target was incorrectly specified and revert. + if (call.callData.length > 0 && call.target.code.length == 0) { + revert InvalidCall(i, calls); + } + + (bool success, ) = call.target.call{ value: call.value }(call.callData); + if (!success) revert CallReverted(i, message.calls); + } + } +``` + +In this example, the Message sub-type allows the user to delegate destination chain contract execution to fillers. However, because transactions are executed via filler, the `msg.sender` would be the `DestinationSettler`, making this `Message` sub-type limited if the target contract authenticates based on the `msg.sender`. Ideally, 7683 orders containing Messages can be combined with smart contract wallets like implementations of [ERC-4337](./eip-4337.md) or [EIP-7702](./eip-7702.md) to allow complete cross-chain delegated execution. + ## Security Considerations - +#### Evaluating settlement contract security + +This ERC is agnostic of how the settlement system validates a 7683 order fulfillment and refunds the filler. In fact, this ERC is designed to delegate the responsibility of evaluating the settlement contract's security to the filler and the application that creates the user's 7683 order. + +This design decision is motivated by the existence of many viable cross-chain messaging systems today offering settlement contracts a variety of tradeoffs. We hope that this standard can eventually support an ERC dedicated to standardizing a safe, trustless, cross-chain verification system. ## Copyright From 5e76057c8f0963309603945da9a672217fcecec2 Mon Sep 17 00:00:00 2001 From: Daniel Gretzke Date: Mon, 4 Nov 2024 21:55:28 +0100 Subject: [PATCH 41/46] Update ERC-7751: Relicense code snippet Merged by EIP-Bot. --- ERCS/erc-7751.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ERCS/erc-7751.md b/ERCS/erc-7751.md index d12ad7670e..ba13155f38 100644 --- a/ERCS/erc-7751.md +++ b/ERCS/erc-7751.md @@ -46,13 +46,13 @@ This ERC does not introduce any backwards incompatibilities. Existing contracts ## Test Cases ```solidity -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: CC0-1.0 pragma solidity 0.8.26; contract Token { mapping(address => uint256) public balanceOf; - event Transfer(address indexed sender, address indexed recipient, uint amount); + event Transfer(address indexed sender, address indexed recipient, uint amount); function transfer(address to, uint256 amount) external returns (bool) { require(balanceOf[msg.sender] >= amount, "insufficient balance"); From 19d49317e7e2a8cc2c3bc0a3a57fd36fd7ed16a8 Mon Sep 17 00:00:00 2001 From: omahs <73983677+omahs@users.noreply.github.com> Date: Tue, 5 Nov 2024 12:52:35 +0100 Subject: [PATCH 42/46] Update ERC-7683: fix typos Merged by EIP-Bot. --- ERCS/erc-7683.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ERCS/erc-7683.md b/ERCS/erc-7683.md index ef27ce5ef3..d56701d538 100644 --- a/ERCS/erc-7683.md +++ b/ERCS/erc-7683.md @@ -30,7 +30,7 @@ The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL - **Filler**: a participant who fulfils a user intent on the destination chain(s) and receives payment as a reward. - **Leg**: a portion of the user intent that can be executed independently from others. All legs must be executed for an intent to be considered fulfilled. - **Origin chain**: the chain where the user sends funds. -- **Settlement System**: a system that custodies user deposits, verifies fills, and pays fillers for the purpose of faciliating intents. +- **Settlement System**: a system that custodies user deposits, verifies fills, and pays fillers for the purpose of facilitating intents. - **Settler**: a contract that implements part of the settlement system on a particular chain. - **User**: for the purposes of this document, the user is the end-user who is sending the order. @@ -106,7 +106,7 @@ struct ResolvedCrossChainOrder { /// @dev The max outputs that the filler will send. It's possible the actual amount depends on the state of the destination /// chain (destination dutch auction, for instance), so these outputs should be considered a cap on filler liabilities. Output[] maxSpent; - /// @dev The minimum outputs that must to be given to the filler as part of order settlement. Similar to maxSpent, it's possible + /// @dev The minimum outputs that must be given to the filler as part of order settlement. Similar to maxSpent, it's possible /// that special order types may not be able to guarantee the exact amount at open time, so this should be considered /// a floor on filler receipts. Output[] minReceived; @@ -115,7 +115,7 @@ struct ResolvedCrossChainOrder { FillInstruction[] fillInstructions; } -/// @notice Tokens that must be receive for a valid order fulfillment +/// @notice Tokens that must be received for a valid order fulfillment struct Output { /// @dev The address of the ERC20 token on the destination chain /// @dev address(0) used as a sentinel for the native token @@ -277,7 +277,7 @@ and fill to evaluate all resulting state transitions without understanding the n ### Cross-compatibility Since this standard is intended to reduce friction for users moving value across chains, non-EVM ecosystems should not be excluded. However, attempting -to pull each non-EVM ecosystem in would dramatically increase the size and complexity of this standard, while ommitting any that come in the future. +to pull each non-EVM ecosystem in would dramatically increase the size and complexity of this standard, while omitting any that come in the future. Instead, this standard is intended to be cross-compatible with other ecosystems. It standardizes interfaces and data types on EVM chains, but allows for the creation of sibling standards that define compatible interfaces, data types, and flows within other ecosystems. Intents created within these @@ -299,7 +299,7 @@ When building a standard-compliant settler system around Permit2, the following ### Examples -This is an example of how a 7683 cross-chain value transfer order can include instructions to the filler to execute arbitrary calldata on behalf of the recipient on the destination chain. This calldata execution is performed by the settlement contract atomically within the filler's fill() execution, so the arbitrary contract execution can take advantage of the destination chain recipient's newly transferred value. A hypothetical user in this example would select a `originSettler` that is known to support the `Message` sub-type. +This is an example of how a 7683 cross-chain value transfer order can include instructions to the filler to execute arbitrary calldata on behalf of the recipient on the destination chain. This calldata execution is performed by the settlement contract atomically within the filler's fill() execution, so the arbitrary contract execution can take advantage of the destination chain recipient's newly transferred value. A hypothetical user in this example would select an `originSettler` that is known to support the `Message` sub-type. Let there be a sub-type called `Message`, which is defined by the following structs: @@ -319,7 +319,7 @@ struct Message { } ``` -The `Message` sub-type is designed to be used by a 7683 user to incentivize a filler to to execute arbitrary calldata on a target destination chain contracton the user's behalf. For example, the settlement contract might decode the `orderData` containing the message information as follows: +The `Message` sub-type is designed to be used by a 7683 user to incentivize a filler to execute arbitrary calldata on a target destination chain contract on the user's behalf. For example, the settlement contract might decode the `orderData` containing the message information as follows: ```solidity function fill(bytes32 orderId, bytes calldata originData, bytes calldata fillerData) public { From 4030cd39956c0ad8e677ecd84450ff9e10b6e304 Mon Sep 17 00:00:00 2001 From: Christian Fries Date: Sun, 10 Nov 2024 16:21:33 +0100 Subject: [PATCH 43/46] Website: Minor fixes of names Merged by EIP-Bot. --- ERCS/erc-6123.md | 50 +++++++++--------- assets/erc-6123/contracts/ERC20Settlement.sol | 24 ++++----- .../erc-6123/contracts/IERC20Settlement.sol | 52 +++++++++++++------ assets/erc-6123/contracts/ISDC.sol | 9 ++-- assets/erc-6123/contracts/SDCSingleTrade.sol | 2 +- .../SDCSingleTradePledgedBalance.sol | 14 ++--- assets/erc-6123/doc/sequence.puml | 2 +- assets/erc-6123/doc/sequence.svg | 2 +- assets/erc-6123/package.json | 2 +- assets/erc-6123/test/SDCTests.js | 4 +- 10 files changed, 90 insertions(+), 71 deletions(-) diff --git a/ERCS/erc-6123.md b/ERCS/erc-6123.md index eeedbc2bb2..e9054db0a7 100644 --- a/ERCS/erc-6123.md +++ b/ERCS/erc-6123.md @@ -58,7 +58,7 @@ which can be processed in a completely frictionless way. ### Methods -The following methods specify a Smart Derivative Contract's trade initiation and settlement life cycle. For further information, please also look at the interface documentation ISDC.sol. +The following methods specify a Smart Derivative Contract's trade initiation, trade termination and settlement life cycle. For further information, please also look at the interface documentation ISDC.sol. #### Trade Initiation Phase: `inceptTrade` @@ -89,56 +89,56 @@ The counterparty that called `inceptTrade` has the option to cancel the trade, e function cancelTrade(address withParty, string memory tradeData, int position, int256 paymentAmount, string memory initialSettlementData) external; ``` -#### Trade Settlement Phase: `initiateSettlement` +#### Trade Termination: `requestTermination` -Allows eligible participants (such as counterparties or a delegated agent) to trigger a settlement phase. +Allows an eligible party to request a mutual termination of the trade with the correspondig `tradeId` with a termination amount she is willing to pay and provide further termination terms (e.g. an XML) ```solidity -function initiateSettlement() external; +function requestTradeTermination(string memory tradeId, int256 terminationPayment, string memory terminationTerms) external; ``` -#### Trade Settlement Phase: `performSettlement` +#### Trade Termination: `confirmTradeTermination` -Valuation may be provided on-chain or off-chain via an external oracle service that calculates the settlement or coupon amounts and uses external market data. -This method serves as a callback called from an external oracle providing settlement amount and used settlement data, which also get stored. -The settlement amount will be checked according to contract terms, resulting in either a regular settlement or a termination of the trade. +Allows an eligible party to confirm a previously requested (mutual) trade termination, including termination payment value and termination terms ```solidity -function performSettlement(int256 settlementAmount, string memory settlementData) external; +function confirmTradeTermination(string memory tradeId, int256 terminationPayment, string memory terminationTerms) external; ``` -#### Trade Settlement Phase: `afterTransfer` +#### Trade Termination: `cancelTradeTermination` -This method - either called back from the provided settlement token directly or from an eligible address - completes the settlement transfer. -This might result in a termination or start of the next settlement phase, depending on the provided success flag. -The transactionData is emitted as part of the corresponding event: `TradeSettled` or `TradeTerminated` +The party that initiated `requestTradeTermination` has the option to withdraw the request, e.g., in the case where the termination is not confirmed in a timely manner. ```solidity -function afterTransfer(bool success, string memory transactionData) external; +function cancelTradeTermination(string memory tradeId, int256 terminationPayment, string memory terminationTerms) external; ``` -#### Trade Termination: `requestTermination` +#### Settlement Phase: `initiateSettlement` -Allows an eligible party to request a mutual termination of the trade with the correspondig `tradeId` with a termination amount she is willing to pay and provide further termination terms (e.g. an XML) +Allows eligible participants (such as counterparties or a delegated agent) to trigger a settlement phase. ```solidity -function requestTradeTermination(string memory tradeId, int256 terminationPayment, string memory terminationTerms) external; +function initiateSettlement() external; ``` -#### Trade Termination: `confirmTradeTermination` +#### Settlement Phase: `performSettlement` -Allows an eligible party to confirm a previously requested (mutual) trade termination, including termination payment value and termination terms +Valuation may be provided on-chain or off-chain via an external oracle service that calculates the settlement or coupon amounts and uses external market data. +This method serves as a callback called from an external oracle providing settlement amount and used settlement data, which also get stored. +The settlement amount will be checked according to contract terms, resulting in either a regular settlement or a termination of the trade. ```solidity -function confirmTradeTermination(string memory tradeId, int256 terminationPayment, string memory terminationTerms) external; +function performSettlement(int256 settlementAmount, string memory settlementData) external; ``` -#### Trade Termination: `cancelTradeTermination` +#### Settlement Phase: `afterTransfer` -The party that initiated `requestTradeTermination` has the option to withdraw the request, e.g., in the case where the termination is not confirmed in a timely manner. +This method - either called back from the provided settlement token directly or from an eligible address - completes the settlement transfer. +The transactionData is emitted as part of the corresponding event: `SettlementTransferred` or `SettlementFailed` +This might result in a termination or start of the next settlement phase, depending on the provided success flag. ```solidity -function cancelTradeTermination(string memory tradeId, int256 terminationPayment, string memory terminationTerms) external; +function afterTransfer(bool success, string memory transactionData) external; ``` @@ -223,12 +223,12 @@ Emitted when a settlement is requested. May trigger the settlement phase. event SettlementRequested(address initiator, string tradeData, string lastSettlementData); ``` -#### SettlementEvaluated +#### SettlementDetermined Emitted when the settlement phase is started. ```solidity -event SettlementEvaluated(address initiator, int256 settlementAmount, string settlementData); +event SettlementDetermined(address initiator, int256 settlementAmount, string settlementData); ``` #### SettlementTransferred diff --git a/assets/erc-6123/contracts/ERC20Settlement.sol b/assets/erc-6123/contracts/ERC20Settlement.sol index bd63f3cf3e..c04be0b302 100644 --- a/assets/erc-6123/contracts/ERC20Settlement.sol +++ b/assets/erc-6123/contracts/ERC20Settlement.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: CC0-1.0 -pragma solidity >=0.7.0 <0.9.0; +pragma solidity >=0.7.0; import "./ISDC.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; @@ -38,36 +38,35 @@ contract ERC20Settlement is ERC20, IERC20Settlement{ _mint(to, amount); } - function checkedTransfer(address to, uint256 value, uint256 transactionID) public onlySDC{ + function transferAndCallback(address to, uint256 value, uint256 transactionID, address callbackContract) public onlySDC{ if ( balanceOf(sdcAddress) < value) - ISDC(sdcAddress).afterTransfer(false, Strings.toString(transactionID)); + ISDC(callbackContract).afterTransfer(false, transactionID, Strings.toString(transactionID)); else - ISDC(sdcAddress).afterTransfer(true, Strings.toString(transactionID)); + ISDC(callbackContract).afterTransfer(true, transactionID, Strings.toString(transactionID)); } - function checkedTransferFrom(address from, address to, uint256 value, uint256 transactionID) external view onlySDC { + function transferFromAndCallback(address from, address to, uint256 value, uint256 transactionID, address callbackContract) external view onlySDC { revert("not implemented"); } - function checkedBatchTransfer(address[] memory to, uint256[] memory values, uint256 transactionID ) public onlySDC{ + function transferBatchAndCallback(address[] memory to, uint256[] memory values, uint256 transactionID, address callbackContract) public onlySDC{ require (to.length == values.length, "Array Length mismatch"); uint256 requiredBalance = 0; for(uint256 i = 0; i < values.length; i++) requiredBalance += values[i]; if (balanceOf(msg.sender) < requiredBalance){ - ISDC(sdcAddress).afterTransfer(false, Strings.toString(transactionID)); + ISDC(callbackContract).afterTransfer(false, transactionID, Strings.toString(transactionID)); return; } else{ for(uint256 i = 0; i < to.length; i++){ _transfer(sdcAddress,to[i],values[i]); } - ISDC(sdcAddress).afterTransfer(true, Strings.toString(transactionID)); + ISDC(callbackContract).afterTransfer(true, transactionID, Strings.toString(transactionID)); } } - - function checkedBatchTransferFrom(address[] memory from, address[] memory to, uint256[] memory values, uint256 transactionID ) public onlySDC{ + function transferBatchFromAndCallback(address[] memory from, address[] memory to, uint256[] memory values, uint256 transactionID, address callbackContract) public onlySDC{ require (from.length == to.length, "Array Length mismatch"); require (to.length == values.length, "Array Length mismatch"); for(uint256 i = 0; i < from.length; i++){ @@ -78,7 +77,7 @@ contract ERC20Settlement is ERC20, IERC20Settlement{ totalRequiredBalance += values[j]; } if (balanceOf(fromAddress) < totalRequiredBalance){ - ISDC(sdcAddress).afterTransfer(false, Strings.toString(transactionID)); + ISDC(callbackContract).afterTransfer(false, transactionID, Strings.toString(transactionID)); return; } @@ -86,7 +85,6 @@ contract ERC20Settlement is ERC20, IERC20Settlement{ for(uint256 i = 0; i < to.length; i++){ _transfer(from[i],to[i],values[i]); } - ISDC(sdcAddress).afterTransfer(true, Strings.toString(transactionID)); + ISDC(callbackContract).afterTransfer(true, transactionID, Strings.toString(transactionID)); } - } \ No newline at end of file diff --git a/assets/erc-6123/contracts/IERC20Settlement.sol b/assets/erc-6123/contracts/IERC20Settlement.sol index 0087858989..60b913badb 100644 --- a/assets/erc-6123/contracts/IERC20Settlement.sol +++ b/assets/erc-6123/contracts/IERC20Settlement.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: CC0-1.0 -pragma solidity >=0.7.0 <0.9.0; +pragma solidity >=0.7.0; @@ -7,47 +7,67 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /*------------------------------------------- DESCRIPTION --------------------------------------------------------------------------------------- * @title ERC6123 - Settlement Token Interface - * @dev Settlement Token Interface enhances the ERC20 Token by introducing so called checked transfer functionality which can be used to directly interact with an SDC. - * Checked transfers can be conducted for single or multiple transactions where SDC will receive a success message whether the transfer was executed successfully or not. + * @dev Settlement Token Interface enhances the ERC20 Token by introducing an asynchronous (checked) transfer functionality which can be used to directly interact with an SDC. + * Transfers can be conducted for single or multiple transactions where SDC will receive a success message whether the transfer was executed successfully or not. + * The SDC or callbackContract needs to implemnt a function afterTransfer(bool success, uint256 transactionID, string memory transactionData) */ +interface IERC20Settlement is IERC20 { + /** + * @dev Emitted when a transfer gets requested + * @param from the address from which to transfer + * @param to the address to which to transfer + * @param value the value to transfer + * @param transactionID a transaction ID that may serve as correlation ID, will be passed to the callback. + * @param callbackContract a contract implementing afterTransfer + */ + event TransferRequested(address from, address to, uint256 value, uint256 transactionID, address callbackContract); -interface IERC20Settlement is IERC20 { + /** + * @dev Emitted when a batch transfer gets requested + * @param from the addresses from which to transfer + * @param to the addresses to which to transfer + * @param value the values to transfer + * @param transactionID a transaction ID that may serve as correlation ID, will be passed to the callback. + * @param callbackContract a contract implementing afterTransfer + */ + event TransferBatchRequested(address[] from, address[] to, uint256[] value, uint256 transactionID, address callbackContract); /* * @dev Performs a single transfer from msg.sender balance and checks whether this transfer can be conducted * @param to - receiver * @param value - transfer amount - * @param transactionID + * @param transactionID - an id that will be passed back to the callback + * @param callbackContract - a contract implementing the method afterTransfer(bool success, uint256 transactionID, string memory transactionData) */ - function checkedTransfer(address to, uint256 value, uint256 transactionID) external; + function transferAndCallback(address to, uint256 value, uint256 transactionID, address callbackContract) external; /* * @dev Performs a single transfer to a single addresss and checks whether this transfer can be conducted * @param from - payer * @param to - receiver * @param value - transfer amount - * @param transactionID + * @param transactionID - an id that will be passed back to the callback + * @param callbackContract - a contract implementing the method afterTransfer(bool success, uint256 transactionID, string memory transactionData) */ - function checkedTransferFrom(address from, address to, uint256 value, uint256 transactionID) external ; - + function transferFromAndCallback(address from, address to, uint256 value, uint256 transactionID, address callbackContract) external ; /* * @dev Performs a multiple transfers from msg.sender balance and checks whether these transfers can be conducted * @param to - receivers * @param values - transfer amounts - * @param transactionID + * @param transactionID - an id that will be passed back to the callback + * @param callbackContract - a contract implementing the method afterTransfer(bool success, uint256 transactionID, string memory transactionData) */ - function checkedBatchTransfer(address[] memory to, uint256[] memory values, uint256 transactionID ) external; + function transferBatchAndCallback(address[] memory to, uint256[] memory values, uint256 transactionID, address callbackContract) external; /* * @dev Performs a multiple transfers between multiple addresses and checks whether these transfers can be conducted * @param from - payers * @param to - receivers - * @param value - transfer amounts - * @param transactionID + * @param values - transfer amounts + * @param transactionID - an id that will be passed back to the callback + * @param callbackContract - a contract implementing the method afterTransfer(bool success, uint256 transactionID, string memory transactionData) */ - function checkedBatchTransferFrom(address[] memory from, address[] memory to, uint256[] memory values, uint256 transactionID ) external; - - + function transferBatchFromAndCallback(address[] memory from, address[] memory to, uint256[] memory values, uint256 transactionID, address callbackContract) external; } diff --git a/assets/erc-6123/contracts/ISDC.sol b/assets/erc-6123/contracts/ISDC.sol index 1a2feb6c27..a34b7d1ba2 100644 --- a/assets/erc-6123/contracts/ISDC.sol +++ b/assets/erc-6123/contracts/ISDC.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: CC0-1.0 -pragma solidity >=0.7.0 <0.9.0; +pragma solidity >=0.7.0; /*------------------------------------------- DESCRIPTION ---------------------------------------------------------------------------------------*/ @@ -124,7 +124,7 @@ interface ISDC { * @param settlementAmount the settlement amount. If settlementAmount > 0 then receivingParty receives this amount from other party. If settlementAmount < 0 then other party receives -settlementAmount from receivingParty. * @param settlementData. the tripple (product, previousSettlementData, settlementData) determines the settlementAmount. */ - event SettlementEvaluated(address initiator, int256 settlementAmount, string settlementData); + event SettlementDetermined(address initiator, int256 settlementAmount, string settlementData); /** * @dev Emitted when settlement process has been finished @@ -212,7 +212,7 @@ interface ISDC { /** * @notice Called to trigger according settlement on chain-balances callback for initiateSettlement() event handler - * @dev perform settlement checks, may initiate transfers and emits {SettlementEvaluated} + * @dev perform settlement checks, may initiate transfers and emits {SettlementDetermined} * @param settlementAmount the settlement amount. If settlementAmount > 0 then receivingParty receives this amount from other party. If settlementAmount < 0 then other party receives -settlementAmount from receivingParty. * @param settlementData. the tripple (product, previousSettlementData, settlementData) determines the settlementAmount. */ @@ -222,10 +222,11 @@ interface ISDC { /** * @notice May get called from outside to to finish a transfer (callback). The trade decides on how to proceed based on success flag * @param success tells the protocol whether transfer was successful + * @param transactionID a transaction * @param transactionData data associtated with the transfer, will be emitted via the events. * @dev emit a {SettlementTransferred} or a {SettlementFailed} event. May emit a {TradeTerminated} event. */ - function afterTransfer(bool success, string memory transactionData) external; + function afterTransfer(bool success, uint256 transactionID, string memory transactionData) external; /// Trade termination diff --git a/assets/erc-6123/contracts/SDCSingleTrade.sol b/assets/erc-6123/contracts/SDCSingleTrade.sol index 6c66929650..f9b0190566 100644 --- a/assets/erc-6123/contracts/SDCSingleTrade.sol +++ b/assets/erc-6123/contracts/SDCSingleTrade.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: CC0-1.0 -pragma solidity >=0.7.0 <0.9.0; +pragma solidity >=0.7.0; import "./ISDC.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; diff --git a/assets/erc-6123/contracts/SDCSingleTradePledgedBalance.sol b/assets/erc-6123/contracts/SDCSingleTradePledgedBalance.sol index 265512764c..5d2c610f1a 100644 --- a/assets/erc-6123/contracts/SDCSingleTradePledgedBalance.sol +++ b/assets/erc-6123/contracts/SDCSingleTradePledgedBalance.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: CC0-1.0 -pragma solidity >=0.8.0 <0.9.0; +pragma solidity >=0.8.0; import "./SDCSingleTrade.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; @@ -86,16 +86,16 @@ contract SDCSingleTradePledgedBalance is SDCSingleTrade { address[] memory to = new address[](1); uint256[] memory amounts = new uint256[](1); from[0] = settlementPayer; to[0] = otherParty(settlementPayer); amounts[0] = transferAmount; - emit SettlementEvaluated(msg.sender, settlementAmount, _settlementData); + emit SettlementDetermined(msg.sender, settlementAmount, _settlementData); setTradeState(TradeState.InTransfer); - settlementToken.checkedBatchTransferFrom(from,to,amounts,transactionID); + settlementToken.transferBatchFromAndCallback(from,to,amounts,transactionID, address(this)); } /* * afterTransfer processes SDC depending on success of the respective payment and depending on the current trade state * Good Case: state will be settled, failed settlement will trigger the pledge balance transfer and termination */ - function afterTransfer(bool success, string memory transactionHash) external override { + function afterTransfer(bool success, uint256 transactionID, string memory transactionData) external override { if ( inStateConfirmed()){ if (success){ setTradeState(TradeState.Settled); @@ -163,7 +163,7 @@ contract SDCSingleTradePledgedBalance is SDCSingleTrade { from[1] = party2; to[1] = address(this); amounts[1] = uint(marginRequirements[party2].buffer + marginRequirements[party2].terminationFee ); from[2] = upfrontPayer; to[2] = otherParty(upfrontPayer); amounts[2] = upfrontPayment; uint256 transactionID = uint256(keccak256(abi.encodePacked(from,to,amounts))); - settlementToken.checkedBatchTransferFrom(from,to,amounts,transactionID); // Batched Transfer + settlementToken.transferBatchFromAndCallback(from,to,amounts,transactionID, address(this)); // Batched Transfer } /* @@ -179,7 +179,7 @@ contract SDCSingleTradePledgedBalance is SDCSingleTrade { from[1] = address(this); to[1] = party2; amounts[1] = uint(marginRequirements[party2].buffer + marginRequirements[party2].terminationFee ); // Release buffers from[2] = terminationFeePayer; to[2] = otherParty(terminationFeePayer); amounts[2] = terminationAmount; uint256 transactionID = uint256(keccak256(abi.encodePacked(from,to,amounts))); - settlementToken.checkedBatchTransferFrom(from,to,amounts,transactionID); // Batched Transfer + settlementToken.transferBatchFromAndCallback(from,to,amounts,transactionID, address(this)); // Batched Transfer } /* function which perfoms the "Pledged Booking" in case of failed settlement, transferring open settlement amount as well as termination fee from sdc's own balance @@ -193,7 +193,7 @@ contract SDCSingleTradePledgedBalance is SDCSingleTrade { to[1] = settlementReceiver; amounts[1] = marginRequirements[settlementReceiver].terminationFee + marginRequirements[settlementReceiver].buffer; // Release to[2] = settlementPayer; amounts[2] = marginRequirements[settlementPayer].buffer-transferAmount; // Release of Buffer uint256 transactionID = uint256(keccak256(abi.encodePacked(to,amounts))); - settlementToken.checkedBatchTransfer(to,amounts,transactionID); + settlementToken.transferBatchAndCallback(to,amounts,transactionID, address(this)); } } diff --git a/assets/erc-6123/doc/sequence.puml b/assets/erc-6123/doc/sequence.puml index a240a31445..58322007c5 100644 --- a/assets/erc-6123/doc/sequence.puml +++ b/assets/erc-6123/doc/sequence.puml @@ -62,7 +62,7 @@ ValuationService->EventHandler: return valuation data EventHandler->SDC: callback: tx 'performSettlement' SDC->SDC:Caps Settlement Amount at Margin Buffer Level -SDC-->EventHandler: emit SettlementEvaluated +SDC-->EventHandler: emit SettlementDetermined SDC->SettlementToken: tx 'transferFrom' settlement amount from Paying Party to Receiving Party Balance == TradeState 'inTransfer' == diff --git a/assets/erc-6123/doc/sequence.svg b/assets/erc-6123/doc/sequence.svg index 99362b5977..8b07b4ed5a 100644 --- a/assets/erc-6123/doc/sequence.svg +++ b/assets/erc-6123/doc/sequence.svg @@ -1 +1 @@ -SmartDerivativeContract with Settlement-Token and off-chain Valuation ServiceCP1CP1CP2CP2SDCSDCSettlementTokenSettlementTokenEventHandlerEventHandlerValuationServiceValuationServiceInitialize Tradeallocate balancesallocate balancestx 'deploy' a SDC with token addresstx 'inceptTrade'emit TradeInceptedTradeState 'Incepted'tx 'confirmTrade'validate tradedataemit TradeConfirmedTradeState 'Confirmed'tx 'transferFrom' margin buffers and termination feesto SDC address for CP1 and CP2tx 'transferFrom' optional Upfront Fee from Paying to Receiving PartyTradeState 'inTransfer'callback tx 'afterTransfer'emit TradeActivatedProcessState 'Settled'loop[Every Settlement]tx: 'initiateSettlement'TradeState 'Valuation'emit SettlementRequestedrequest valuation datareturn valuation datacallback: tx 'performSettlement'Caps Settlement Amount at Margin Buffer Levelemit SettlementEvaluatedtx 'transferFrom' settlement amount from Paying Party to Receiving Party BalanceTradeState 'inTransfer'alt[Transfer Check]callback tx 'afterTransfer'[success]emit SettlementTransferredTradeState 'Settled'[fail]emit SettlementFailedtx 'transfer' Settlement Amount from SDC Balance to Receiving Partytx 'transfer' Termination Fee from SDC Balance to Receiving Partytx 'transfer' - Release remainigBalances to partiesemit TradeTerminatedTradeState 'Terminated' \ No newline at end of file +SmartDerivativeContract with Settlement-Token and off-chain Valuation ServiceCP1CP1CP2CP2SDCSDCSettlementTokenSettlementTokenEventHandlerEventHandlerValuationServiceValuationServiceInitialize Tradeallocate balancesallocate balancestx 'deploy' a SDC with token addresstx 'inceptTrade'emit TradeInceptedTradeState 'Incepted'tx 'confirmTrade'validate tradedataemit TradeConfirmedTradeState 'Confirmed'tx 'transferFrom' margin buffers and termination feesto SDC address for CP1 and CP2tx 'transferFrom' optional Upfront Fee from Paying to Receiving PartyTradeState 'inTransfer'callback tx 'afterTransfer'emit TradeActivatedProcessState 'Settled'loop[Every Settlement]tx: 'initiateSettlement'TradeState 'Valuation'emit SettlementRequestedrequest valuation datareturn valuation datacallback: tx 'performSettlement'Caps Settlement Amount at Margin Buffer Levelemit SettlementDeterminedtx 'transferFrom' settlement amount from Paying Party to Receiving Party BalanceTradeState 'inTransfer'alt[Transfer Check]callback tx 'afterTransfer'[success]emit SettlementTransferredTradeState 'Settled'[fail]emit SettlementFailedtx 'transfer' Settlement Amount from SDC Balance to Receiving Partytx 'transfer' Termination Fee from SDC Balance to Receiving Partytx 'transfer' - Release remainigBalances to partiesemit TradeTerminatedTradeState 'Terminated' \ No newline at end of file diff --git a/assets/erc-6123/package.json b/assets/erc-6123/package.json index 2286d3af93..b72cb2e7be 100644 --- a/assets/erc-6123/package.json +++ b/assets/erc-6123/package.json @@ -1,6 +1,6 @@ { "name": "@finmath.net/sdc", - "version": "0.4.2", + "version": "0.4.3", "description": "Solidity Smart Derivative Contracts", "author": "Christian Fries, Peter Kohl-Landgraf, Alexandros Korpis", "license": "ISC", diff --git a/assets/erc-6123/test/SDCTests.js b/assets/erc-6123/test/SDCTests.js index 22e39646d8..536019c563 100644 --- a/assets/erc-6123/test/SDCTests.js +++ b/assets/erc-6123/test/SDCTests.js @@ -261,7 +261,7 @@ describe("Livecycle Unit-Tests for SDC Plege Balance", () => { await expect(initSettlementPhase).to.emit(sdc, "SettlementRequested"); const performSettlementCall = sdc.connect(counterparty1).performSettlement(settlementAmount,"settlementData"); - await expect(performSettlementCall).to.emit(sdc, "SettlementEvaluated"); + await expect(performSettlementCall).to.emit(sdc, "SettlementDetermined"); let trade_state = await sdc.connect(counterparty1).getTradeState(); await expect(trade_state).equal(TradeState.Settled); let sdc_balance = await token.connect(counterparty1).balanceOf(sdc.address); @@ -291,7 +291,7 @@ describe("Livecycle Unit-Tests for SDC Plege Balance", () => { await expect(initSettlementPhase).to.emit(sdc, "SettlementRequested"); const performSettlementCall = sdc.connect(counterparty1).performSettlement(settlementAmount,"settlementData"); - await expect(performSettlementCall).to.emit(sdc, "SettlementEvaluated"); + await expect(performSettlementCall).to.emit(sdc, "SettlementDetermined"); let trade_state = await sdc.connect(counterparty1).getTradeState(); let sdc_balance = await token.connect(counterparty1).balanceOf(sdc.address); let cp1_balance = await token.connect(counterparty1).balanceOf(counterparty1.address); From 12349b3e69da169f3363a92deef795cc1f5747d5 Mon Sep 17 00:00:00 2001 From: Christian Fries Date: Sun, 10 Nov 2024 20:04:27 +0100 Subject: [PATCH 44/46] Update ERC-6123: Fixes to reference implementation of Settlement Token Merged by EIP-Bot. --- ERCS/erc-6123.md | 2 +- assets/erc-6123/contracts/ERC20Settlement.sol | 16 +++++++++------- assets/erc-6123/contracts/ISDC.sol | 10 +++++++--- .../contracts/SDCSingleTradePledgedBalance.sol | 5 +++-- assets/erc-6123/package.json | 2 +- 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/ERCS/erc-6123.md b/ERCS/erc-6123.md index e9054db0a7..dc6fb80aa3 100644 --- a/ERCS/erc-6123.md +++ b/ERCS/erc-6123.md @@ -138,7 +138,7 @@ The transactionData is emitted as part of the corresponding event: `SettlementTr This might result in a termination or start of the next settlement phase, depending on the provided success flag. ```solidity -function afterTransfer(bool success, string memory transactionData) external; +function afterTransfer(bool success, uint256 transactionID, string memory transactionData) external; ``` diff --git a/assets/erc-6123/contracts/ERC20Settlement.sol b/assets/erc-6123/contracts/ERC20Settlement.sol index c04be0b302..0fa805e952 100644 --- a/assets/erc-6123/contracts/ERC20Settlement.sol +++ b/assets/erc-6123/contracts/ERC20Settlement.sol @@ -7,8 +7,6 @@ import "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; import "./IERC20Settlement.sol"; -contract ERC20Settlement is ERC20, IERC20Settlement{ - /*------------------------------------------- DESCRIPTION --------------------------------------------------------------------------------------- * @title Reference (example) Implementation for Settlement Token Interface * @dev This token performs transfers on-chain. @@ -16,7 +14,7 @@ contract ERC20Settlement is ERC20, IERC20Settlement{ * Only SDC can call checkedTransfers * Settlement Token calls back the referenced SDC by calling "afterTransfer" with a success flag. Depending on this SDC perfoms next state change */ - +contract ERC20Settlement is ERC20, IERC20Settlement{ modifier onlySDC() { require(msg.sender == sdcAddress, "Only allowed to be called from SDC Address"); _; @@ -39,10 +37,13 @@ contract ERC20Settlement is ERC20, IERC20Settlement{ } function transferAndCallback(address to, uint256 value, uint256 transactionID, address callbackContract) public onlySDC{ - if ( balanceOf(sdcAddress) < value) + if ( balanceOf(msg.sender) < value) { ISDC(callbackContract).afterTransfer(false, transactionID, Strings.toString(transactionID)); - else + } + else { + _transfer(msg.sender,to,value); ISDC(callbackContract).afterTransfer(true, transactionID, Strings.toString(transactionID)); + } } function transferFromAndCallback(address from, address to, uint256 value, uint256 transactionID, address callbackContract) external view onlySDC { @@ -52,15 +53,16 @@ contract ERC20Settlement is ERC20, IERC20Settlement{ function transferBatchAndCallback(address[] memory to, uint256[] memory values, uint256 transactionID, address callbackContract) public onlySDC{ require (to.length == values.length, "Array Length mismatch"); uint256 requiredBalance = 0; - for(uint256 i = 0; i < values.length; i++) + for(uint256 i = 0; i < values.length; i++) { requiredBalance += values[i]; + } if (balanceOf(msg.sender) < requiredBalance){ ISDC(callbackContract).afterTransfer(false, transactionID, Strings.toString(transactionID)); return; } else{ for(uint256 i = 0; i < to.length; i++){ - _transfer(sdcAddress,to[i],values[i]); + _transfer(msg.sender,to[i],values[i]); } ISDC(callbackContract).afterTransfer(true, transactionID, Strings.toString(transactionID)); } diff --git a/assets/erc-6123/contracts/ISDC.sol b/assets/erc-6123/contracts/ISDC.sol index a34b7d1ba2..7b1088b131 100644 --- a/assets/erc-6123/contracts/ISDC.sol +++ b/assets/erc-6123/contracts/ISDC.sol @@ -128,13 +128,17 @@ interface ISDC { /** * @dev Emitted when settlement process has been finished + * @param transactionID a transaction id + * @param transactionData data associtated with the transfer, will be emitted via the events. */ - event SettlementTransferred(string transactionData); + event SettlementTransferred(uint256 transactionID, string transactionData); /** * @dev Emitted when settlement process has been finished + * @param transactionID a transaction id + * @param transactionData data associtated with the transfer, will be emitted via the events. */ - event SettlementFailed(string transactionData); + event SettlementFailed(uint256 transactionID, string transactionData); /* Events related to trade termination */ @@ -222,7 +226,7 @@ interface ISDC { /** * @notice May get called from outside to to finish a transfer (callback). The trade decides on how to proceed based on success flag * @param success tells the protocol whether transfer was successful - * @param transactionID a transaction + * @param transactionID a transaction id * @param transactionData data associtated with the transfer, will be emitted via the events. * @dev emit a {SettlementTransferred} or a {SettlementFailed} event. May emit a {TradeTerminated} event. */ diff --git a/assets/erc-6123/contracts/SDCSingleTradePledgedBalance.sol b/assets/erc-6123/contracts/SDCSingleTradePledgedBalance.sol index 5d2c610f1a..25586d214c 100644 --- a/assets/erc-6123/contracts/SDCSingleTradePledgedBalance.sol +++ b/assets/erc-6123/contracts/SDCSingleTradePledgedBalance.sol @@ -109,11 +109,12 @@ contract SDCSingleTradePledgedBalance is SDCSingleTrade { else if ( inStateTransfer() ){ if (success){ setTradeState(TradeState.Settled); - emit SettlementTransferred("Settlement Settled - Pledge Transfer"); + emit SettlementTransferred(transactionID, "Settlement Settled - Pledge Transfer"); } else{ // Settlement & Pledge Case: transferAmount is transferred from SDC balance (i.e. pledged balance). - int256 settlementAmount = settlementAmounts[settlementAmounts.length-1]; setTradeState(TradeState.InTermination); + emit SettlementFailed(transactionID, "Settlement Failed - Pledge Transfer"); + int256 settlementAmount = settlementAmounts[settlementAmounts.length-1]; processTerminationWithPledge(settlementAmount); emit TradeTerminated(tradeID, "Settlement Failed - Pledge Transfer"); } diff --git a/assets/erc-6123/package.json b/assets/erc-6123/package.json index b72cb2e7be..c8857b4772 100644 --- a/assets/erc-6123/package.json +++ b/assets/erc-6123/package.json @@ -1,6 +1,6 @@ { "name": "@finmath.net/sdc", - "version": "0.4.3", + "version": "0.4.4", "description": "Solidity Smart Derivative Contracts", "author": "Christian Fries, Peter Kohl-Landgraf, Alexandros Korpis", "license": "ISC", From 3526d5fbad07a404531fe7e5b5ae9d3d2a6125cf Mon Sep 17 00:00:00 2001 From: Radek Date: Tue, 12 Nov 2024 10:06:40 +0100 Subject: [PATCH 45/46] Update ERC-7699: Update erc-7699.md - suggested minor fixes Merged by EIP-Bot. --- ERCS/erc-7699.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ERCS/erc-7699.md b/ERCS/erc-7699.md index d078ad2985..b0497b8b60 100644 --- a/ERCS/erc-7699.md +++ b/ERCS/erc-7699.md @@ -49,7 +49,7 @@ These `transfer` and `transferFrom` functions, in addition to the standard trans The corresponding ERC-20 `Transfer` event MUST be emitted following the `TransferReference` event, ideally immediately afterwards for the client to be able to seek the associated `Transfer` event log record. -Emitted `loggedReference` MIGHT be the exact copy of the `transferReference` (when less then 33 bytes) or the derived data from the rich `transferReference` structure and other processing. This is up to the implementer. One MUST NOT expect the `transferReference` and `loggedReference` data are equal. +Emitted `loggedReference` MAY be the exact copy of the `transferReference` (when less then 33 bytes) or the derived data from the rich `transferReference` structure and other processing. This is up to the implementer. One MUST NOT expect the `transferReference` and `loggedReference` data to be equal. The `loggedReference` parameter MAY contain any data of bytes32 type. @@ -57,7 +57,7 @@ The `transferReference` parameter MAY be empty. In this case and only in this ca The `transferReference` parameter is not limited in length by design, users are motivated to keep it short due to calldata and execution gas costs. -The `TransferReference` event MUST NOT be anonymous. This is to ensure that the event signature is logged and can be used as a filter. +The `TransferReference` event MUST NOT be declared with the `anonymous` specifier. This is to ensure that the event signature is logged and can be used as a filter. Transfers of 0 amount MUST be treated as normal transfers and fire the `TransferReference` event alike. @@ -195,7 +195,7 @@ contract ERC20TransferReference is ERC20, IERC7699 { ### Privacy Considerations -Reference data privacy: Including payment references in token transfers may expose sensitive information about the transaction or the parties involved. Implementers and users SHOULD carefully consider the privacy implications and ensure that payment references do not reveal sensitive information. To mitigate this risk, implementers can consider using encryption or other privacy-enhancing techniques to protect payment reference data. +Reference data privacy: Including payment references in token transfers may expose sensitive information about the transaction or the parties involved. Implementers and users should carefully consider the privacy implications and ensure that payment references do not reveal sensitive information. To mitigate this risk, implementers can consider using encryption or other privacy-enhancing techniques to protect payment reference data. Example: With reference 0x20240002 logged, transaction is publicly exposing that this is related to the second invoice of the recipient in 2024. From 508b0ec746a9270b8b9e4465721737dc8afe9ce8 Mon Sep 17 00:00:00 2001 From: Ryan Ghods Date: Tue, 12 Nov 2024 23:53:20 -0800 Subject: [PATCH 46/46] Update ERC-7496: Update erc-7496.md - trait metadata as required Merged by EIP-Bot. --- ERCS/erc-7496.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7496.md b/ERCS/erc-7496.md index fd8290ce5d..c762b1aee7 100644 --- a/ERCS/erc-7496.md +++ b/ERCS/erc-7496.md @@ -55,7 +55,7 @@ The `traitKey` SHOULD be a `keccak256` hash of a human readable trait name. ### Metadata -Trait metadata is an optional way to define additional information about which traits are present in a contract, how to parse and display trait values, and permissions for setting trait values. +Trait metadata is necessary to provide information about which traits are present in a contract, how to display trait names and values, and other optional features. The trait metadata must be compliant with the [specified schema](../assets/eip-7496/DynamicTraitsSchema.json).