<style>
@import url(https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&display=swap);@import url('https://fonts.googleapis.com/css2?family=Source Code Pro:wght@400;500;600;700&display=swap');ul{opacity:1;}table{border:none !important;}a,code,pre,tt{overflow-wrap:break-word;word-wrap:break-word}.chroma .lntable,.chroma .lntd{margin:0;border:0;padding:0}pre,table{width:100%}.findings-count td,.findings-count th,.rating-critical,.rating-high,.rating-informational,.rating-low,.rating-medium,.status-closed,.status-open,.status-resolved{text-align:center}.rating-critical,.rating-high,.rating-informational,.rating-low,.rating-medium,.status-closed,.status-open,.status-resolved,a,h1,h2,h3{font-weight:500}:root{--color-link:#f66263;--color-heading:#f66263;--color-codeblock:#f5f2f0;--color-codeblock-border:#f5f2f0;--color-critical:#cc7ab9;--color-high:#ff6263;--color-medium:#f68463;--color-low:#f6b263;--color-informational:#6ba2f6;--color-open:#f6d263;--color-closed:#b6b6b6;--color-resolved:#9fbf9f;--size-200:0.694rem;--size-300:0.833rem;--size-400:1rem;--size-500:1.2rem;--size-600:1.44rem;--size-700:1.728rem;--size-800:2.074rem;--size-900:2.488rem}.report-container{color:#222;font-family:Montserrat,sans-serif;line-height:1.6;margin:1rem;font-size:var(--size-400)}a{color:var(--color-link)}@media screen and (min-width:1600px){.report-main{display:grid;grid-gap:1em}.toc{grid-column:1;max-width:30em}.frontpage-logo,.frontpage-subtitle,.frontpage-title,.report{grid-column:2}}@media screen and (max-width:1599px){ .report-main{ margin: 0 auto;max-width:70em} }h1,h2,h3,h4,h5,h6{margin-bottom:0}.toc>ul>li>a,dt,h4,h5,h6,table th{font-weight:600}h1,h2{color:var(--color-heading)}h3,h4,h5,h6{color:#444 !important}h1{font-size:var(--size-800)}h2{font-size:var(--size-700)}h3{font-size:var(--size-600) } .audit-text-formatting .report-main h3{font-size:var(--size-600) }h4{font-size:var(--size-500)}h1 strong,h2 strong,h3 strong,h4 strong{font-weight:400;font-size:.7em;font-family:"Source Code Pro",monospace}h2 strong::after{content:"\a";white-space:pre}code,pre,tt{font-family:"Source Code Pro",monospace,sans-serif;background-color:var(--color-codeblock);white-space:pre-wrap}code,tt{padding:1px 3px;border-radius:2px}pre{box-sizing:border-box;padding:10px;overflow:auto;word-break:break-all}pre code,tt{font-size:inherit;background:0 0;border:none;padding:0}.findings code,h2 code{background-color:inherit;border-width:0}@media screen and (min-width:600px){dl{display:grid;grid-gap:0.5em}dt{grid-column:1}dd{grid-column:2}}@media screen and (max-width:599px){dl{display:block}}table{background-color:inherit;max-width:100%;min-width:100%;border:none;font-size:.9em}table thead th{border-bottom:2px solid #222}table td,table th{text-align:left;border:none}table,td,th{border-collapse:collapse}.findings-count thead tr th:first-of-type{border-style:none}.findings-count tbody td:first-child{text-align:right;width:6em;padding-right:.75em;border-right:2px solid #222;font-weight:600}.findings-count td:nth-child(2),.rating-critical{background-color:var(--color-critical)}.findings-count td:nth-child(3),.rating-high{background-color:var(--color-high)}.findings-count td:nth-child(4),.rating-medium{background-color:var(--color-medium)}.findings-count td:nth-child(5),.rating-low{background-color:var(--color-low)}.findings-count td:nth-child(6),.rating-informational{background-color:var(--color-informational)}.status-open{background-color:var(--color-open)}.status-closed{background-color:var(--color-closed)}.status-resolved{background-color:var(--color-resolved)}.findings td:first-of-type{white-space:nowrap;word-break:keep-all;font-family:"Source Code Pro",monospace;vertical-align:top}.findings td:nth-of-type(2){vertical-align:bottom}@media screen{.audit-header,.report{max-width:65rem}h1{margin-top:3em}h2{margin-top:2em}table th{padding:6px}table td{padding:8px 6px}.findings td:nth-of-type(2){min-width:2em}}.metadata td:last-of-type{background-color:#eee}.metadata td:first-of-type,.metadata td:nth-of-type(2){width:8em}.toc ul{list-style:none;margin-left:0;padding-left:0}.toc li ul{margin-left:3em}.toc{counter-reset:tocSectionCounter}.toc>ul>li::before{content:counter(tocSectionCounter) ". ";font-weight:600;padding-right:4px}.toc>ul>li{counter-increment:tocSectionCounter}.report{counter-reset:sectionCounter}.report h1::before{content:counter(sectionCounter) ". ";font-weight:400;padding-right:6px}.report h1{counter-increment:sectionCounter}hr{display:none}@media print{.landing-header{display:none}.toc li a,h1,h2{color:#222}dd,dt{margin:.2em 0;break-inside:avoid}dl,pre{page-break-inside:auto;break-inside:auto}dd,dt,pre{padding:0}.toc li a,.toc li a::after,pre{background-color:#fff}td{min-width:2em}pre,td{word-break:break-word}h1,h2{margin-top:0}#document-control,.break-before,h1,hr{page-break-before:always}h1{font-size:18pt}h2{font-size:16pt}h3{font-size:14pt}.frontpage-subtitle,h4{font-size:12pt}.toc,p,ul,ol,dl{font-size:11pt}summary{list-style:none;font-size:1.1em;margin-bottom:1em}.toc{background:0 0;max-width:100%;counter-reset:page;line-height:1.6}.toc li a::after{content:target-counter(attr(href),page);float:right;position:absolute;right:0;padding-left:3px}.toc li ul{margin-left:1.5em}.toc li{overflow-x:hidden;max-width:98.5%;text-align:left}.toc li ul li::after{content:".............................................." ".............................................." ".............................................." "........";float:left;width:0;letter-spacing:6px}footer,header{display:none}dd,li,p,p *{text-align:justify}dl{width:100%;display:flex;flex-wrap:wrap}dt{flex:1;min-width:30%}dd{flex:1;min-width:65%}.frontpage-logo{margin-top:75mm;width:65mm;padding-bottom:1cm}.report-container{height:auto}pre{display:inline;font-size:.9em}pre:first-child,pre:last-child{padding:0;margin:0;background-color:#fff}pre *{white-space:pre-wrap;background-color:var(--color-codeblock);padding:1px;word-wrap:normal}.findings td{max-width:20em;overflow-wrap:break-word;text-wrap:balance}.frontpage-title{font-size:20pt;font-weight:700}.frontpage-subtitle{page-break-after:always;}.metadata td{padding:.3em}td{padding:4px}}.page-header{margin-top:-1cm;opacity:.8;position:running(pageHeaderRunning)}.page-header svg{width:34mm}@media screen{.page-header,.frontpage-subtitle,.frontpage-title,.frontpage-logo{display:none}.frontpage-subtitle,.frontpage-title{text-align:center}.frontpage-logo{width:10em;padding-bottom:.5em;margin-left:auto;margin-right:auto}.frontpage-title{font-size:var(--size-900);font-weight:700}.frontpage-subtitle{font-size:var(--size-500)}}@page{size:A4;margin:2cm 1.6cm;bleed:6mm}@page{@bottom-center{content:"𝗣𝗨𝗕𝗟𝗜𝗖 \A hello@iosiro.com";white-space:pre;color:#b7b7b7;font-size:9pt;font-family:Montserrat,sans-serif}@bottom-right-corner{content:counter(page);font-size:9pt}@top-center{content:element(pageHeaderRunning)}}@page:first{text-align:center;@top-center{content:none}@bottom-right-corner{content:none}}.chroma .lnlinks,a{text-decoration:none}.chroma .lntd,.codequality td{vertical-align:top;font-size:.9em}.chroma .ge,.chroma .sd{font-style:italic}.chroma .gh,.chroma .gp,.chroma .gs,.chroma .gu,.chroma .nc,.chroma .nd,.chroma .ni,.chroma .nl,.chroma .nn,.chroma .nt,.chroma .se,summary{font-weight:700}.bg,.chroma{background-color:var(--color-codeblock)}.chroma .lnlinks{outline:0;color:inherit}.chroma .lntable{border-spacing:0}.chroma .hl{background-color:#d8d8d8}.chroma .ln,.chroma .lnt{white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f7f7f}.chroma .line{display:flex}.chroma .k,.chroma .kc,.chroma .kd,.chroma .kn,.chroma .kr,.chroma .ow{color:#007020;font-weight:700}.chroma .cp,.chroma .cpf,.chroma .kp,.chroma .nb,.chroma .ne{color:#007020}.chroma .kt{color:#902000}.chroma .dl,.chroma .na,.chroma .s,.chroma .s1,.chroma .s2,.chroma .sa,.chroma .sb,.chroma .sc,.chroma .sd,.chroma .se,.chroma .sh{color:#4070a0}.chroma .nc,.chroma .nn{color:#0e84b5}.chroma .no{color:#60add5}.chroma .nd{color:#555}.chroma .ni{color:#d55537}.chroma .nf{color:#06287e}.chroma .nl{color:#002070}.chroma .nt{color:#062873}.chroma .nv{color:#bb60d5}.chroma .si{color:#70a0d0}.chroma .gp,.chroma .sx{color:#c65d09}.chroma .sr{color:#235388}.chroma .ss{color:#517918}.chroma .il,.chroma .m,.chroma .mb,.chroma .mf,.chroma .mh,.chroma .mi,.chroma .mo{color:#40a070}.chroma .o{color:#666}.chroma .c,.chroma .c1,.chroma .ch,.chroma .cm{color:#60a0b0;font-style:italic}.chroma .cs{color:#60a0b0;background-color:#fff0f0}.chroma .gd{color:#a00000}.chroma .gr{color:red}.chroma .gh{color:navy}.chroma .gi{color:#00a000}.chroma .go{color:#888}.chroma .gu{color:purple}.chroma .gt{color:#04d}.chroma .gl{text-decoration:underline}.chroma .w{color:#bbb}.container{max-width:100%}
</style>
<div class="report-container">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" style="display:none;">
<defs>
<symbol id="iosiro-logo" viewBox="0 0 1233 312" preserveAspectRatio="xMidYMid meet">
<g fill="#061f45">
<path d="M171.5 300.6 c-3.9 -1.7 -9.5 -4.6 -12.5 -6.5 -5.1 -3.2 -21 -15 -21 -15.6 0 -0.2 6.1 -3.5 13.5 -7.4 7.4 -3.8 17.2 -9.6 21.8 -12.7 11.1 -7.7 24.4 -21.3 29 -29.5 8.2 -14.7 9.4 -21.4 11.2 -62 1.5 -36.7 3 -46.9 8.5 -62.1 10.1 -27.6 28.2 -43.3 68 -58.8 20.3 -8 31.8 -14.8 42.4 -25.2 l8.9 -8.8 -0.7 5.7 c-1.1 9.2 -4.7 15.7 -13.4 24.2 -9.3 9.1 -20.2 16 -49.9 31.5 -22.9 12 -27 14.8 -33.3 22.7 -8.4 10.6 -10.6 21.1 -12.5 59.2 -1.6 32.3 -2.4 39.8 -5.6 52.7 -7.4 29.9 -24.7 52.9 -51.2 68.2 l-7.7 4.4 6.4 3.6 6.4 3.5 7.9 -4.1 c4.3 -2.2 11.7 -6.7 16.5 -9.9 9.8 -6.6 30.5 -26 40.1 -37.5 8.9 -10.6 21.7 -30.5 28 -43.3 l5.2 -10.7 9.5 -4.5 c5.2 -2.5 9.6 -4.4 9.9 -4.2 1.6 1.7 -13.3 32.8 -22.4 46.7 -22.3 34 -54.5 62.6 -91.3 81.2 l-4.7 2.4 -7 -3.2z"></path>
<path d="M582.1 272 c-19.3 -4.1 -31.7 -11.4 -45.4 -26.8 -14.2 -16 -19.7 -31.4 -19.7 -55.5 0.1 -22.2 4.9 -36.2 17.4 -50.9 9.3 -10.9 16.1 -16.5 25.8 -21.4 14.5 -7.3 21.7 -8.9 39.8 -8.9 18.3 0 23.5 1.2 38.5 8.5 20.6 10 36.7 29.7 43.1 53 2.6 9.2 2.5 31.8 0 41.4 -7.3 27.2 -27.1 48.7 -53 57.3 -10.6 3.4 -11.8 3.6 -26.6 3.9 -8.5 0.2 -17.5 -0.1 -19.9 -0.6z m31 -31.4 c13.1 -2.8 21.4 -9.3 27.7 -21.3 5.1 -10 6.6 -16.5 6.5 -28.8 0 -22.7 -9.7 -39.6 -26.9 -46.9 -5.9 -2.5 -8.5 -3 -17.7 -3.4 -6.4 -0.3 -12.7 0.1 -15.5 0.8 -25.7 6.4 -40 33.3 -33.7 63.5 2.9 13.8 10.9 25.6 21.7 31.9 8.6 5 25.2 6.9 37.9 4.2z"></path>
<path d="M754 271.9 c-11.5 -3.2 -17.4 -6.4 -24.9 -13.9 -6.6 -6.6 -12.6 -14.9 -14.6 -20.1 -0.5 -1.4 2.3 -3.1 14.1 -8.8 8.1 -3.9 14.9 -7 15 -6.8 0.2 0.2 2.1 3 4.3 6.4 4.7 7.3 9 10.7 15.4 12.4 5.8 1.4 14.3 0.7 18.7 -1.6 6.2 -3.2 8.8 -14 5.1 -21.4 -3.4 -6.6 -9.5 -10.9 -28.6 -20.2 -21.5 -10.4 -27.5 -15.1 -32.7 -25.7 -3.1 -6.3 -3.3 -7.2 -3.3 -17.7 0.1 -9.1 0.5 -12 2.4 -16.8 5.3 -13.4 16.5 -23.3 31.5 -27.9 5.6 -1.7 8.6 -2 16.7 -1.6 8.9 0.4 10.7 0.9 17.4 4.2 8.9 4.4 17.2 12.1 20.9 19.4 1.4 2.8 2.6 5.6 2.6 6.1 0 0.9 -27.9 15.6 -28.4 14.9 -0.2 -0.2 -1.4 -2 -2.8 -4.1 -5.3 -7.9 -13.3 -11.2 -20.2 -8.3 -4 1.7 -7.6 6.8 -7.6 10.9 0 6.9 5.4 11.8 20.3 18.4 18 7.9 32.9 16.8 39.6 23.4 1.8 1.9 4.7 6.3 6.4 9.9 2.7 5.6 3.2 7.9 3.5 16.2 0.5 11.8 -1.7 20.3 -7.6 29.3 -7.6 11.7 -18.3 19.3 -32.2 23 -6.2 1.7 -25.4 1.9 -31 0.4z"></path>
<path d="M1118 271 c-17.1 -4.3 -27.7 -10.6 -40.6 -24.3 -5.2 -5.4 -8.2 -9.8 -12.2 -17.7 -6.9 -13.9 -8.4 -19.7 -8.9 -36 -0.6 -16.4 0.9 -24.3 6.6 -36.6 5.5 -11.7 11.7 -20 20.5 -27.7 9.2 -8.1 17.3 -12.6 29.6 -16.8 8 -2.7 11.4 -3.3 21.9 -3.7 17.7 -0.7 28.4 1.5 43.8 9 9.7 4.7 14.7 8.7 24 19.1 14.8 16.5 19.6 29.6 19.7 54.2 0 12.8 -0.3 16.2 -2.3 23.5 -3.4 12.4 -9.3 23 -18 32.2 -12.8 13.7 -23.3 19.9 -41 24.4 -12.1 3.1 -31.5 3.3 -43.1 0.4z m32.9 -30.1 c8.9 -1.6 14.3 -4.2 21.1 -10.5 10.4 -9.7 15.3 -22.3 15.3 -39.4 0 -22.3 -9.5 -39.2 -26.6 -47.1 -6.5 -3 -8.3 -3.3 -18.3 -3.7 -17 -0.7 -27.7 3.1 -37.1 13.1 -8.5 8.9 -13.3 22.2 -13.3 36.8 -0.1 36.5 23.6 56.8 58.9 50.8z"></path>
<path d="M116.7 259.8 c-21.5 -21.4 -40.1 -47.4 -49.3 -69 -1.9 -4.5 -3.3 -8.2 -3.2 -8.3 0.2 -0.2 6.4 1.9 13.8 4.6 39.7 14.5 52.8 20.7 56.3 26.6 2.3 4 2.4 9.6 0.2 14.8 l-1.8 4 -1.2 -4.8 c-1.6 -6.3 -7.9 -12.8 -16.1 -16.7 -5.8 -2.8 -22.3 -7.4 -23.2 -6.5 -0.8 0.7 20.8 30.1 29.1 39.6 l4.9 5.6 7.6 -4.1 c16.5 -8.9 28.7 -25.3 31.8 -42.6 3.5 -20.6 -2.9 -41.1 -18.1 -56.9 -12.9 -13.5 -24.5 -20.2 -49.7 -28.9 -17.7 -6.1 -23.4 -8.5 -31.3 -13.1 -20.4 -11.6 -34.4 -28.2 -39 -46.2 -2 -7.5 -2 -20.9 -0.2 -28.9 l1.3 -5.5 0.8 6.5 c2.4 21.7 11.4 39 26.7 51.6 9.4 7.7 18.7 12.1 44.4 20.9 58.6 20.2 75.6 34.1 85.1 69.2 3.7 13.8 4 33.3 0.6 44.1 -6.8 21.5 -25.1 39.9 -49.2 49.4 -11.5 4.6 -9.9 5 -20.3 -5.4z"></path>
<path d="M441 190.5 l0 -78.5 17.5 0 17.5 0 0 78.5 0 78.5 -17.5 0 -17.5 0 0 -78.5z"></path>
<path d="M858 190.5 l0 -78.5 18 0 18 0 0 78.5 0 78.5 -18 0 -18 0 0 -78.5z"></path>
<path d="M942 190.5 l0 -78.5 18 0 18 0 0 7.1 0 7.2 4.5 -4.2 c6.7 -6.2 15.9 -11.7 21.6 -13.1 8.5 -2.1 21 -0.8 29.9 2.9 4.1 1.7 8.1 3.5 8.8 4 1.1 0.6 -0.4 4.3 -6.3 16.2 -4.3 8.5 -7.9 15.6 -8.1 15.8 -0.2 0.2 -3.2 -0.9 -6.6 -2.5 -5.3 -2.4 -7.6 -2.9 -14.3 -2.9 -7 0 -8.7 0.4 -13.4 3 -6.6 3.7 -10.4 8.2 -13.3 16 -2.3 5.9 -2.3 6.9 -2.6 56.8 l-0.3 50.7 -17.9 0 -18 0 0 -78.5z"></path>
<path d="M145 191.5 c-7.1 -7.2 -17 -14 -29.8 -20.4 -10.1 -5.1 -33.5 -13.6 -44.2 -16.1 -13.5 -3.2 -32.8 -13.7 -42 -23 -6.9 -6.8 -13.5 -17.3 -16.6 -26.6 -2.3 -6.6 -2.7 -9.7 -2.8 -18.9 -0.1 -11.4 1.1 -23.2 2.2 -22 0.4 0.3 1.4 4.6 2.3 9.4 3.6 18.6 10.6 32 23.8 45.2 11.8 11.7 18.1 15.2 39.9 21.9 25.8 8 39.3 14.5 53.6 26.1 10 8 20.9 24.4 19.4 28.9 -0.2 0.6 -2.8 -1.5 -5.8 -4.5z"></path>
<path d="M240 182.6 c0 -2.9 4.2 -12.6 7.5 -17.1 7.7 -10.9 17.3 -18.4 40 -31.2 18.3 -10.3 23.6 -14.3 37.8 -28.2 l11.7 -11.6 0 3.5 c0 10 -5.7 21.6 -15.1 31.1 -7.3 7.4 -13.7 11.2 -32.1 19.3 -21.6 9.6 -32.7 16.6 -43 27.4 -3.8 3.8 -6.8 6.9 -6.8 6.8z"></path>
<path d="M244 145.8 c0 -3.2 4.3 -15.5 7.8 -22.2 4.1 -7.9 14.2 -18.7 22.2 -23.8 3 -2 11.6 -6.7 19 -10.7 16.7 -8.8 31.3 -19.6 44.9 -33.2 l10.4 -10.3 -0.6 4.2 c-3.3 20.1 -19.8 37.3 -50.7 52.7 -6.3 3.2 -14 7.5 -17.2 9.6 -5.9 4 -25.8 23.1 -32.2 30.8 -2.1 2.6 -3.6 3.8 -3.6 2.9z"></path>
<path d="M182.1 139.6 c-6.5 -8.4 -21.1 -21.9 -26.3 -24.3 -4.1 -2 -5 -3 -8.2 -9.6 -5 -10.4 -15.6 -21.6 -24.4 -25.9 -6.4 -3.1 -7.3 -3.3 -18.3 -3.3 -13.8 0 -15.9 1 -15.9 7.8 0 3.6 -0.2 3.8 -1.7 2.6 -3 -2.5 -7.3 -10.2 -7.3 -13.2 0 -9.4 12.7 -18.9 29.4 -21.8 5.5 -1 8.2 -2.1 12.1 -5.1 7.3 -5.6 13.7 -7.2 26.5 -6.6 13.4 0.7 20.2 3 46.3 15.4 22.9 11 24.1 11.5 28.5 12.3 l3.2 0.6 -3.6 5 c-9.8 13.7 -18.1 38.4 -19.6 58.5 -0.5 5.9 -2.8 -13.8 -2.8 -23.7 0 -9.8 1.9 -21.5 4.4 -27.5 0.9 -2.1 1.6 -4 1.6 -4.3 0 -0.2 -4.2 -2.4 -9.2 -4.8 -5.1 -2.4 -13.3 -7 -18.3 -10.1 -15.3 -9.7 -33.9 -13.8 -42 -9.4 l-3 1.6 5 0.7 c6.9 0.9 18.2 4.3 19.1 5.7 0.5 0.8 0.1 0.9 -1.1 0.4 -1.1 -0.4 -10.7 -1 -21.4 -1.3 -21 -0.6 -29.5 0.3 -32.5 3.6 -1.6 1.7 -1.3 1.8 5.3 2.5 13.2 1.2 28 7.2 39.8 16 11.7 8.9 21.8 21.8 30.1 38.7 4.1 8.5 9.7 23.8 8.9 24.5 -0.2 0.3 -2.3 -2 -4.6 -5z"></path>
<path d="M57.1 65.6 l-6.4 -6.4 2.9 -12.2 2.9 -12.3 11 -3.9 c56.8 -20.4 121.7 -24.1 184 -10.6 12 2.6 32.2 8.6 36.2 10.7 0.7 0.4 -3.1 2.5 -8.8 5 l-10 4.4 -7.4 -2.2 c-10.1 -2.9 -23.7 -5.6 -38.6 -7.7 -16.6 -2.4 -59.3 -2.4 -79.4 0 -26.3 3 -71.7 12.6 -73.4 15.5 -0.4 0.6 -1.8 6.8 -3.1 13.6 -1.3 6.9 -2.6 12.5 -3 12.5 -0.3 0 -3.4 -2.9 -6.9 -6.4z"></path>
<path d="M449.3 66.9 c-12.3 -6.1 -17 -20.9 -10.4 -32.4 5.2 -9 12.9 -12.5 24.6 -11 6.5 0.8 11.1 4.1 14.9 10.9 11 19 -9.7 42.1 -29.1 32.5z"></path>
<path d="M867.5 67.2 c-5 -2.3 -10.3 -7.6 -12.1 -11.9 -1.8 -4.3 -1.8 -15.2 0.1 -19.6 2.2 -5.4 9.8 -11.5 15.2 -12.3 6.4 -0.9 13.9 0.2 17.9 2.7 7.6 4.7 12.7 16.5 10.5 24.5 -1.5 5.4 -6.1 11.7 -11.2 15.1 -5.4 3.6 -14.5 4.3 -20.4 1.5z"></path>
</g>
</symbol>
</defs>
<use href="#iosiro-logo"></use>
</svg>
<div class="page-header" id="page-header">
<svg version="1.0">
<use href="#iosiro-logo"></use>
</svg>
</div>
<main class="report-main">
<svg version="1.0" class="frontpage-logo">
<use href="#iosiro-logo"></use>
</svg>
<div class="frontpage-title">Accounts V4</div>
<div class="frontpage-subtitle">Infinex, 9 December 2024</div>
<nav class="toc">
<h1>Contents</h1>
<ul>
<li>
<a href="#introduction">Introduction</a></li>
<li>
<a href="#disclaimer">Disclaimer</a></li>
<li>
<a href="#methodology">Methodology</a></li>
<li>
<a href="#audit-findings">Audit findings</a><ul>
<li>
<a href="#io-ifx-rviv-001-missing-validation">IO-IFX-RVIV-001 Missing validation</a></li>
<li>
<a href="#io-ifx-rviv-005-type-hash-does-not-conform-to-eip-712">IO-IFX-RVIV-005 Type hash does not conform to EIP-712</a></li>
</ul>
</li>
<li>
<a href="#code-quality-improvement-suggestions">Code quality improvement suggestions</a></li>
<li>
<a href="#specification">Specification</a></li>
</ul>
</nav>
<article class="report">
<h1 id="introduction">Introduction</h1>
<p>iosiro was commissioned by Infinex to perform a smart contract audit of the Infinex Accounts V4 release. A single auditor conducted the audit between 20 November 2024 and 3 December 2024, using 3 audit days.</p>
<h4 id="overview">Overview</h4>
<p>During the audit, one low-risk issue related to the incorrect implementation of EIP-712 and one informational issue relating to the lack of validation for specific requests were reported. Several code quality improvements and defence-in-depth suggestions were also provided and are detailed in this report.</p>
<p>The table below shows the reported findings' status at the assessment's conclusion.</p>
<table class="findings-count">
<thead>
<tr>
<th> </th>
<th>Critical</th>
<th>High</th>
<th>Medium</th>
<th>Low</th>
<th>Informational</th>
</tr>
</thead>
<tbody>
<tr>
<td>Open</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>1</td>
</tr>
<tr>
<td>Resolved</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>0</td>
</tr>
<tr>
<td>Closed</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
</tbody>
</table>
<h4 id="scope">Scope</h4>
<p>The assessment focused on the source files listed below, with all other files considered out of scope. Any out-of-scope code interacting with the assessed code was presumed to operate correctly without introducing functional or security vulnerabilities.</p>
<ul>
<li><strong>Project name:</strong> <code>infinex-contracts</code></li>
<li><strong>Initial audit commit:</strong> <a href="https://github.com/infinex-xyz/infinex-contracts/tree/42253373a0fec113f9fad879ff0fa1ece99a0892"><code>4225337</code></a></li>
<li><strong>Final review commit:</strong> <a href="https://github.com/infinex-xyz/infinex-contracts/tree/0e142681656af4854ca5eeef5421da5612230b92"><code>0e14268</code></a></li>
</ul>
<table>
<thead>
<tr>
<th>File</th>
<th>SHA256 - <a href="https://github.com/infinex-xyz/infinex-contracts/tree/0e142681656af4854ca5eeef5421da5612230b92"><code>0e14268</code></a></th>
</tr>
</thead>
<tbody>
<tr>
<td width="55%">src/accounts/utils/RequestTypes.sol</td>
<td>47f7d9e0aef9cb95b439fdff5d01c232528650d5f62d29c86f4fcb67135f8c42</td>
</tr>
<tr>
<td>src/accounts/utils/SecurityModifiers.sol</td>
<td>7c5a6dde338befc3983cf13fecf088e24347f05f431602ca7e3f08cf91c03305</td>
</tr>
<tr>
<td>src/accounts/utils/WithdrawUtil.sol</td>
<td>f7a4e0576bb7045e87c005ec27808d141edefe189b40032c41e1365f928628e0</td>
</tr>
<tr>
<td>src/accounts/utils/AccountConstants.sol</td>
<td>e6f4420118e4b841d54a2e31f65af8905c86f01068bba4270efdca2f867c0e98</td>
</tr>
<tr>
<td>src/accounts/utils/SecurityUtils.sol</td>
<td>f5a3c07dde9a117ee23c5fc129e81f3a591ce934f29854e7c639202eae5e81f0</td>
</tr>
<tr>
<td>src/accounts/storage/App.sol</td>
<td>b2373c34fd674b0f31d0e509c1b5765a6f662adafd9f0407ad0ed86d26fad8df</td>
</tr>
<tr>
<td>src/accounts/storage/Recovery.sol</td>
<td>40dbef83e013a53d3e4948e486ccc18d03b21bb83a55737558a4692d11906176</td>
</tr>
<tr>
<td>src/accounts/storage/Cosigning.sol</td>
<td>c0ef1b04c501b381fe4e1f57ea8bc998e8209a7c9a749caded17a49690c76d57</td>
</tr>
<tr>
<td>src/accounts/storage/Account.sol</td>
<td>246704d480ac812c1d729dc68345dc415d80bc36e8572cbded606fe28324c21a</td>
</tr>
<tr>
<td>src/accounts/storage/Bridge.sol</td>
<td>cc8f253b656a46d605b53e1e19664448d4560d412032913383641d7861abe188</td>
</tr>
<tr>
<td>src/accounts/storage/Withdrawal.sol</td>
<td>4ebd51230bf0a903b7dfb8fedd840f32b73693c3a83ea09908ca45203a29546e</td>
</tr>
<tr>
<td>src/accounts/storage/SecurityKeys.sol</td>
<td>b4177aa5ae5d56cac6c05bbbfea50211b6acc2c95325c235cb18e90cdbfe30fb</td>
</tr>
<tr>
<td>src/accounts/storage/EIP712.sol</td>
<td>4823614863254c55d2fc7e63b9887686cca6ac8fc14c7ac8a32aaca7e264d1ab</td>
</tr>
<tr>
<td>src/accounts/modules/WithdrawModule.sol</td>
<td>999e0d7c2bbd3a6de6431c6bcd47158eb73eaf3d0b3b01aada10ce8f16c1e2ee</td>
</tr>
<tr>
<td>src/accounts/modules/BaseModule.sol</td>
<td>1e42e73a9ffd4515bd49e97be7beaab1748045bf75ac874596fa7db411c7c9fb</td>
</tr>
<tr>
<td>src/accounts/modules/RecoveryModule.sol</td>
<td>49b9d78223e29786a16f37c80a909842826c0ef8d8a78b71b6d7c8545178265f</td>
</tr>
<tr>
<td>src/accounts/modules/AccountUtilsModule.sol</td>
<td>248198167e03918429fc72254fa229238903cc97d83695fb0cd07b7a8ad94514</td>
</tr>
<tr>
<td>src/accounts/modules/AppModule.sol</td>
<td>a2c9794154fcbde5b9f14c8be3b1bb888a0e786e2bd1d579331605271a87d5b7</td>
</tr>
<tr>
<td>src/accounts/modules/TransferModule.sol</td>
<td>7e6849ae05bf0e8c219d58771d4e59906448b51d88bb2b0999295442677dccb4</td>
</tr>
<tr>
<td>src/accounts/modules/BridgingModule.sol</td>
<td>334f4582588276809d3968ebd13d78b31c8f03f9b2ebfdd2720245cdcec124ad</td>
</tr>
<tr>
<td>src/beacons/InfinexProtocolConfigBeacon.sol</td>
<td>51bde80280667d5a1ef27446d60c3e8002d2927bc63da5528374f825bb3fbbc7</td>
</tr>
<tr>
<td width="55%">src/libraries/NonStandardToken.sol</td>
<td>6deddd61fca03af57adf52840568bcf50f77cc5b4704af9dd23ceed1b556bcbf</td>
</tr>
</tbody>
</table>
<p>A specification is available in the <a href="#specification">Specification section</a> of this report.</p>
<h1 id="disclaimer">Disclaimer</h1>
<p>This report aims to provide an overview of the assessed smart contracts' risk exposure and a guide to improving their security posture by addressing identified issues. The audit, limited to specific source code at the time of review, sought to:</p>
<ul>
<li>Identify potential security flaws.</li>
<li>Verify that the smart contracts' functionality aligns with their documentation.</li>
</ul>
<p>Off-chain components, such as backend web application code, keeper functionality, and deployment scripts were explicitly not in-scope of this audit.</p>
<p>Given the unregulated nature and ease of cryptocurrency transfers, operations involving these assets face a high risk from cyber attacks. Maintaining the highest security level is crucial, necessitating a proactive and adaptive approach that accounts for the experimental and rapidly evolving nature of blockchain technology. To encourage secure code development, developers should:</p>
<ul>
<li>Integrate security throughout the development lifecycle.</li>
<li>Employ defensive programming to mitigate the risks posed by unexpected events.</li>
<li>Adhere to current best practices wherever possible.</li>
</ul>
<h1 id="methodology">Methodology</h1>
<p>The audit was conducted using the techniques described below.</p>
<dl>
<dt>Code review</dt>
<dd>The source code was manually inspected to identify potential security flaws. Code review is a useful approach for detecting security flaws, discrepancies between the specification and implementation, design improvements, and high-risk areas of the system.</dd>
<dt>Dynamic analysis</dt>
<dd>The contracts were compiled, deployed, and tested in a test environment, both manually and through the test suite provided. Dynamic analysis was used to identify additional edge cases, confirm that the code was functional, and to validate the reported issues.</dd>
<dt>Automated analysis</dt>
<dd>Automated tooling was used to detect the presence of various types of security vulnerabilities. Static analysis results were reviewed manually and any false positives were removed. Any true positive results are included in this report.</dd>
</dl>
<h1 id="audit-findings">Audit findings</h1>
<p>The table below provides an overview of the audit's findings. Detailed write-ups are provided below.</p>
<table class="findings">
<thead>
<tr>
<th>ID</th>
<th>Issue</th>
<th>Risk</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="#IO-IFX-RVIV-001">IO-IFX-RVIV-001</a></td>
<td>Missing validation</td>
<td class="rating-informational">Informational</td>
<td class="status-open">Open</td>
</tr>
<tr>
<td><a href="#IO-IFX-RVIV-005">IO-IFX-RVIV-005</a></td>
<td>Type hash does not conform to EIP-712</td>
<td class="rating-low">Low</td>
<td class="status-resolved">Resolved</td>
</tr>
</tbody>
</table>
<p>Each issue identified during the audit has been assigned a risk rating. The rating is determined based on the criteria outlined below.</p>
<dl>
<dt>Critical risk</dt>
<dd>The issue could result in the theft of funds from the contract or its users.</dd>
<dt>High risk</dt>
<dd>The issue could result in the loss of funds for the contract owner or its users.</dd>
<dt>Medium risk</dt>
<dd>The issue resulted in the code being dysfunctional or the specification being implemented incorrectly.</dd>
<dt>Low risk</dt>
<dd>A design or best practice issue that could affect the ordinary functioning of the contract.</dd>
<dt>Informational</dt>
<dd>An improvement related to best practice or a suboptimal design pattern.</dd>
</dl>
<p>In addition to a risk rating, each issue is assigned a status:</p>
<dl>
<dt>Open</dt>
<dd>The issue remained present in the code as of the final commit reviewed and may still pose a risk.</dd>
<dt>Resolved</dt>
<dd>The issue was identified during the audit and has since been satisfactorily addressed, removing the risk it posed.</dd>
<dt>Closed</dt>
<dd>The issue was identified during the audit and acknowledged by the developers as an acceptable risk without actioning any change.</dd>
</dl>
<a name="IO-IFX-RVIV-001"></a><h2 id="io-ifx-rviv-001-missing-validation" class="break-before"><strong>IO-IFX-RVIV-001</strong> Missing validation</h2>
<table class="metadata">
<tbody>
<tr>
<td class="rating-informational">Informational</td>
<td class="status-open">Open</td>
<td><a href="https://github.com/infinex-xyz/infinex-contracts/blob/d08bde067095c70c8ad03458311a118ceb7576f8/src/accounts/storage/Cosigning.sol#L12">Cosigning.sol#L12</a></td>
</tr>
</tbody>
</table>
<p>The validation of transfer request properties is inconsistent and differs between conceptually identical functions.</p>
<p>Infinex uses passkeys to sign transactions, which does not provide users with a clear indication of the data being signed. Therefore, any errors in how structs are encoded could result in transfer requests containing zero-valued parameters. In the worst case, if the recipient parameter was misaligned, funds could accidentally be transferred to the zero address.</p>
<h3 id="recommendation">Recommendation</h3>
<p>Validation checks should be added for some or all relevant parameters of the following functions:</p>
<ul>
<li><code>_transferERC20</code>: The zero address should not be permitted as the <code>destination</code> or <code>token</code> parameters.</li>
<li><code>_transferERC1155</code>: None of the transfer request's properties are validated. Only non-zero values for <code>destination</code>, <code>token</code> and <code>amount</code> should be permitted.</li>
<li><code>_transferERC1155Batch</code>: None of the transfer request's properties are validated. Only non-zero values for the <code>destination</code> and <code>token</code> address should be permitted. An empty <code>tokenIds</code> array should not be permitted.</li>
</ul>
<h3 id="client-response">Client response</h3>
<p>Infinex acknowledged the issue and indicated that it will be addressed in a future release.</p>
<a name="IO-IFX-RVIV-005"></a><h2 id="io-ifx-rviv-005-type-hash-does-not-conform-to-eip-712" class="break-before"><strong>IO-IFX-RVIV-005</strong> Type hash does not conform to EIP-712</h2>
<table class="metadata">
<tbody>
<tr>
<td class="rating-low">Low</td>
<td class="status-resolved">Resolved</td>
<td><a href="https://github.com/infinex-xyz/infinex-contracts/blob/d08bde067095c70c8ad03458311a118ceb7576f8/src/accounts/storage/Cosigning.sol#L12">Cosigning.sol#L12</a></td>
</tr>
</tbody>
</table>
<p>The function, <code>_createAndSignTransferRequest</code>, used to derive the struct hash for the <code>TransferRequest</code> struct, was not correctly implemented as per <a href="https://eips.ethereum.org/EIPS/eip-712">EIP-712</a>.</p>
<p>When calculating an EIP-712 type hash, non-fixed arrays and dynamic length elements should be tightly packed using <code>abi.encodePacked</code> and then hashed. The <code>_createAndSignTransferRequest</code> function incorrectly used <code>abi.encode</code> for the <code>amounts</code>, <code>tokenIds</code> and <code>data</code> elements.</p>
<p>Additionally, the <code>encodeType</code> definition should contain the original data types, as it provides the blueprint for generating the type hash. Without the original data types, frontend libraries will not be able to encode the data correctly.</p>
<h3 id="recommendation-1">Recommendation</h3>
<p>The <code>TRANSFER_REQUEST_TYPEHASH</code> definition should be updated to reflect the correct data types, as shown below:</p>
<pre tabindex="0" class="chroma"><code><span class="line"><span class="cl"><span class="n">TransferRequest</span><span class="p">(</span><span class="kt">bytes4</span> <span class="nb">selector</span><span class="p">,</span><span class="kt">address</span> <span class="n">destination</span><span class="p">,</span><span class="kt">address</span> <span class="n">token</span><span class="p">,</span><span class="kt">uint256</span> <span class="n">nonStandardIndex</span><span class="p">,</span><span class="kt">uint256</span> <span class="n">tokenId</span><span class="p">,</span><span class="kt">uint256</span> <span class="n">amount</span><span class="p">,</span><span class="kt">uint256</span><span class="p">[]</span> <span class="n">amounts</span><span class="p">,</span><span class="kt">uint256</span><span class="p">[]</span> <span class="n">tokenIds</span><span class="p">,</span><span class="kt">bytes</span> <span class="nb">data</span><span class="p">,</span><span class="kt">uint256</span> <span class="n">nonce</span><span class="p">)</span>
</span></span></code></pre><p>The dynamic length array elements should be encoded using <code>abi.encodedPacked</code> before hashing in <code>_createAndSignTransferRequest</code>.</p>
<h3 id="client-response-1">Client response</h3>
<p>Fixed in <a href="https://github.com/infinex-xyz/infinex-contracts/commit/14cfd332787ff017aec8e36c0f7986f1bf893269">14cfd33</a> and <a href="https://github.com/infinex-xyz/infinex-contracts/commit/f322ba3f70af339e488e4df06a80c608bb059223">f322ba3</a>.</p>
<h1 id="code-quality-improvement-suggestions">Code quality improvement suggestions</h1>
<p>Code improvement suggestions without security implications are listed below.</p>
<table class="codequality">
<thead>
<tr>
<th>#</th>
<th>Location</th>
<th>Details</th>
</tr>
</thead>
<tbody>
<tr>
<td width="20%"><strong>IO-IFX-PNVT-002</strong></td>
<td><a href="https://github.com/infinex-xyz/infinex-contracts/blob/42253373a0fec113f9fad879ff0fa1ece99a0892/src/accounts/utils/WithdrawUtil.sol#L153">WithdrawUtil.sol#L153</a>, <a href="https://github.com/infinex-xyz/infinex-contracts/blob/42253373a0fec113f9fad879ff0fa1ece99a0892/src/libraries/NonStandardToken.sol#L21">NonStandardToken.sol#L21</a></td>
<td>Hardcoded values are used at various points in the codebase as identifiers for non-standard NFT tokens, which can lead to a mismatch between the different lookup tables. To improve the codebase's readability and maintainability, the non-standard NFT identifiers should be defined as an <code>enum</code> in the <code>NonStandardToken</code> library.</td>
</tr>
<tr>
<td><strong>IO-IFX-PNVT-003</strong></td>
<td><a href="https://github.com/infinex-xyz/infinex-contracts/blob/42253373a0fec113f9fad879ff0fa1ece99a0892/src/accounts/utils/WithdrawUtil.sol#L153">WithdrawUtil.sol#L153</a></td>
<td>The function <code>_transferNonStandardNFT</code> reimplements the transfer logic for supported non-standard NFTs, as opposed to using the <code>transfer()</code> function already defined in the <code>NonStandardToken</code> library.</td>
</tr>
<tr>
<td><strong>IO-IFX-PNVT-004</strong></td>
<td><a href="https://github.com/infinex-xyz/infinex-contracts/blob/42253373a0fec113f9fad879ff0fa1ece99a0892/src/accounts/utils/WithdrawUtil.sol#L152">WithdrawUtil.sol#L152</a></td>
<td>The <code>_transferNonStandardNFT</code> function emits a <code>TransferNonStandardNFTExecuted</code> event even though another event with identical properties always precedes it. To avoid duplicating state, the event from <code>_transferNonStandardNFT</code> should be removed. This will result in only <code>WithdrawalNonStandardNFTExecuted</code> or <code>NonStandardNFTTransferredToApp</code> events being emitted.</td>
</tr>
</tbody>
</table>
<ol>
<li>Won't fix.</li>
<li>Fixed in commit <a href="https://github.com/infinex-xyz/infinex-contracts/commit/d43ede49be3c0c8e0ad7683391e697679e2d19ba">d43ede4</a>.</li>
<li>Fixed in commit <a href="https://github.com/infinex-xyz/infinex-contracts/commit/d43ede49be3c0c8e0ad7683391e697679e2d19ba">d43ede4</a>.</li>
</ol>
<h1 id="specification">Specification</h1>
<p>The following section outlines the system's intended functionality at a high level, as derived from the codebase implementation and the specification in <a href="https://proposals.infinex.xyz/xips/xip-91">XIP-91</a>. Any conflicts or ambiguities should be flagged with the auditing team for resolution.</p>
<h3 id="transfers">Transfers</h3>
<p>A key enhancement to Infinex Accounts is the introduction of functionality to transfer assets to external addresses outside the Infinex ecosystem.</p>
<p>To mitigate risks such as phishing scams and other common Web3 attacks, all transfer requests require cosignature by Infinex. This cosignature process is expected to include multi-factor authentication (e.g., TOTP) to ensure the secure use of the Platform Key.</p>
<h3 id="recovery-address-migration">Recovery address migration</h3>
<p>Users now have the ability to update their nominated recovery address, a feature that was previously restricted to a one-time setup, typically during account creation. To prevent misuse, any change to the recovery address must be cosigned by Infinex. It is anticipated that Infinex will enforce multi-factor authentication or employ a risk-based strategy to validate such requests.</p>
<h3 id="compatibility-enhancements">Compatibility enhancements</h3>
<p>Several compatibility updates have been introduced, including:</p>
<ul>
<li><em>ERC721A Support:</em> Enabling batch transfers for ERC721A tokens, such as Infinex's Patron NFT.</li>
<li><em>Non-Standard NFTs:</em> Adding transfer, recovery, and withdrawal support for non-standard NFTs, including CryptoPunks and EtherRocks.</li>
<li><em>EIP-1271 Compliance:</em> Introducing a public function to validate whether the sudo key has signed a given message hash.</li>
</ul>
</article>
</main>
</div>