<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) !important}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">Staked Thales Betting Proxy Smart Contract Audit</div>
<div class="frontpage-subtitle">Thales, 11 September 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-thl-tbp-001-precision-loss-could-allow-for-draining-of-entire-reward-pool">IO-THL-TBP-001 Precision loss could allow for draining of entire reward pool</a></li>
<li>
<a href="#io-thl-tbp-002-betting-proxy-could-be-abused-to-bypass-unstake-cooldown-period">IO-THL-TBP-002 Betting proxy could be abused to bypass unstake cooldown period</a></li>
<li>
<a href="#io-thl-tbp-003-no-validation-of-collateral-type-for-live-trades">IO-THL-TBP-003 No validation of collateral type for live trades</a></li>
<li>
<a href="#io-thl-tbp-004-merge-account-does-not-check-for-active-tickets-on-source-account">IO-THL-TBP-004 Merge account does not check for active tickets on source account</a></li>
</ul>
</li>
<li>
<a href="#code-quality-improvement-suggestions">Code quality improvement suggestions</a></li>
<li>
<a href="#specification">Specification</a><ul>
<li>
<a href="#staking-thales-betting-proxy">Staking Thales Betting Proxy</a></li>
<li>
<a href="#staking-thales-changes">Staking Thales Changes</a></li>
<li>
<a href="#other-changes">Other Changes</a></li>
</ul>
</li>
<li>
<a href="#test-coverage-report">Test coverage report</a></li>
</ul>
</nav>
<article class="report">
<h1 id="introduction">Introduction</h1>
<p>iosiro was commissioned by Thales to perform an audit of their new Staked Thales Betting Proxy smart contract and changes made to other related contracts to facilitate this new betting mechanism. The audit was conducted between the 2nd and the 5th of September 2024, using 4 audit days.</p>
<h4 id="overview">Overview</h4>
<p>The audit uncovered one high-risk issue which was subsequently remediated. This issue would have allowed malicious stakers to claim more than their share of rewards from the <code>StakingThales</code> contract. Several low-risk issues as well as code quality and design suggestions were found and are detailed in this report. A breakdown of the issues reported and their status at the conclusion of the audit is provided below:</p>
<table class="findings-count">
<thead>
<tr>
<th> </th>
<th>Critical</th>
<th>High</th>
<th>Medium</th>
<th>Low</th>
</tr>
</thead>
<tbody>
<tr>
<td>Open</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td>Resolved</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
</tr>
<tr>
<td>Closed</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>2</td>
</tr>
</tbody>
</table>
<h4 id="scope">Scope</h4>
<p>The assessment focused on source file 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> thales-markets/contracts and thales-markets/contracts-v2</li>
<li><strong>Initial audit commit:</strong> <a href="https://github.com/thales-markets/contracts-v2/tree/012072f78e4fdb57db78591036582729e41cb660">012072f</a> and <a href="https://github.com/thales-markets/contracts/tree/20c51000f5003d1edfec565d4151030a9219b308">20c5100</a></li>
<li><strong>Final review commit:</strong> <a href="https://github.com/thales-markets/contracts-v2/tree/b0219e33240ed65cab9d1a03a9b42c9e061586d8">b0219e3</a> and <a href="https://github.com/thales-markets/contracts/tree/82c756309278eda3197fe75dd012cb077e6e95a2">82c7563</a></li>
<li><strong>Files:</strong> <code>contracts/contracts/EscrowAndStaking/StakingThales.sol</code>, <code>contracts-v2/contracts/core/AMM/SportsAMMV2.sol</code>, <code>contracts-v2/contracts/core/StakingThalesBetting/StakingThalesBettingProxy.sol</code>, <code>contracts-v2/contracts/core/LiveTrading/LiveTradingProcessor.sol</code></li>
</ul>
<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-THL-TBP-001">IO-THL-TBP-001</a></td>
<td>Precision loss could allow for draining of entire reward pool</td>
<td class="rating-high">High</td>
<td class="status-resolved">Resolved</td>
</tr>
<tr>
<td><a href="#IO-THL-TBP-002">IO-THL-TBP-002</a></td>
<td>Betting proxy could be abused to bypass unstake cooldown period</td>
<td class="rating-low">Low</td>
<td class="status-closed">Closed</td>
</tr>
<tr>
<td><a href="#IO-THL-TBP-003">IO-THL-TBP-003</a></td>
<td>No validation of collateral type for live trades</td>
<td class="rating-low">Low</td>
<td class="status-resolved">Resolved</td>
</tr>
<tr>
<td><a href="#IO-THL-TBP-004">IO-THL-TBP-004</a></td>
<td>Merge account does not check for active tickets on source account</td>
<td class="rating-low">Low</td>
<td class="status-closed">Closed</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-THL-TBP-001"></a><h2 id="io-thl-tbp-001-precision-loss-could-allow-for-draining-of-entire-reward-pool" class="break-before"><strong>IO-THL-TBP-001</strong> Precision loss could allow for draining of entire reward pool</h2>
<table class="metadata">
<tbody>
<tr>
<td class="rating-high">High</td>
<td class="status-resolved">Resolved</td>
<td><a href="https://github.com/thales-markets/contracts/blob/20c51000f5003d1edfec565d4151030a9219b308/contracts/EscrowAndStaking/StakingThales.sol#L652-L653">StakingThales.sol#L652-L653</a></td>
</tr>
</tbody>
</table>
<p>The <code>StakingThales</code> contract enforces the claiming of rewards before any modifications to an account’s staking balance. This is done by calling <code>StakingThales::_calculateAvailableRewardsToClaim()</code> and, if the amount of rewards available to claim is non-zero, call <code>StakingThales::_claimReward()</code>. Once the rewards are claimed, the <code>_lastRewardsClaimedPeriod</code> value for the account is updated to the current rewards period. This prevents the account from claiming more than once per period. This control is also intended to ensure that an account cannot increase its staked balance and immediately claim rewards in the current period, as rewards due are calculated as a proportion of the total amount staked and escrowed in the previous period.</p>
<p>The snippet below from <code>StakingThales::getBaseReward()</code> shows how the base reward value, that forms the basis of available rewards, is calculated for an account:</p>
<pre tabindex="0" class="chroma"><code><span class="line"><span class="cl"><span class="n">_baseRewards</span> <span class="o">=</span> <span class="n">_stakedBalances</span><span class="p">[</span><span class="n">account</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">iEscrowThales</span><span class="p">.</span><span class="n">getStakedEscrowedBalanceForRewards</span><span class="p">(</span><span class="n">account</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="n">mul</span><span class="p">(</span><span class="n">currentPeriodRewards</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="n">div</span><span class="p">(</span><span class="n">totalStakedLastPeriodEnd</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">totalEscrowedLastPeriodEnd</span><span class="p">));</span>
</span></span></code></pre><p>Should the current staked balance be a small value, such as 1 wei, then the base reward value would be zero in most cases where <code>currentPeriodRewards</code>, <code>totalStakedLastPeriodEnd</code>, and <code>totalEscrowedLastPeriodEnd</code> are 18 decimal values. As a result <code>_calculateAvailableRewardsToClaim()</code> will also return zero and the logic within the following if block will not execute:</p>
<pre tabindex="0" class="chroma"><code><span class="line"><span class="cl"><span class="k">if</span> <span class="p">(</span><span class="n">_calculateAvailableRewardsToClaim</span><span class="p">(</span><span class="n">_account</span><span class="p">)</span> <span class="o">></span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="n">_claimReward</span><span class="p">(</span><span class="n">_account</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre><p>Consequently, <code>_lastRewardsClaimedPeriod</code> will not be updated and it would be possible to increase an account’s staked balance from a small initial value and then immediately claim rewards against the new larger balance. As these rewards are proportional to the current staked amount and the amount escrowed for the last reward period, users could receive more rewards than they should.</p>
<p>A malicious user could abuse this to claim the entire <code>feeToken</code> balance of the <code>StakingThales</code> contract, preventing other users from claiming rewards. It may also be possible to do the same with the THALES token balance of the <code>ThalesStakingRewardsPool</code>.</p>
<h3 id="recommendation">Recommendation</h3>
<p>The if statement in <code>StakingThales::_modifyStakingBalance()</code> that calculates available rewards should instead check whether <code>_lastRewardsClaimedPeriod[account] != periodsOfStaking</code> before calling <code>_claimRewards()</code> . This will ensure that <code>_lastRewardsClaimedPeriod</code> for an account is always updated before sensitive actions, such as staking and unstaking, while also distributing any applicable rewards. To improve readability, this if block could be put in a modifier that can then be applied across all functions that modify an account’s balance.</p>
<p>Alternatively, <code>_lastRewardsClaimedPeriod</code> for an account should always be set to the <code>periodsOfStaking</code> before any modifications to staking balances are made.</p>
<h3 id="client-response">Client response</h3>
<p>Fixed in <a href="https://github.com/thales-markets/contracts/pull/475/commits/914415cc0c8002c68f3cb9dcfb736e7beee5a548">914415c</a>.</p>
<a name="IO-THL-TBP-002"></a><h2 id="io-thl-tbp-002-betting-proxy-could-be-abused-to-bypass-unstake-cooldown-period" class="break-before"><strong>IO-THL-TBP-002</strong> Betting proxy could be abused to bypass unstake cooldown period</h2>
<table class="metadata">
<tbody>
<tr>
<td class="rating-low">Low</td>
<td class="status-closed">Closed</td>
<td><a href="https://github.com/thales-markets/contracts-v2/blob/012072f78e4fdb57db78591036582729e41cb660/contracts/core/StakingThalesBetting/StakingThalesBettingProxy.sol">StakingThalesBettingProxy.sol</a></td>
</tr>
</tbody>
</table>
<p>The new staked THALES betting mechanism could provide a way for malicious users to bypass the unstake cooldown period by making a delta neutral bet that will most likely result in a loss for the staked account. By placing a bet on the opposite side of the market to their staked account, the user stands to win back liquid THALES.</p>
<p>This issue is inherent in the design of this new mechanism. Based on the limited review of <code>StakingThales</code> and related contracts such as <code>EscrowThales</code>, its impact at the time of this audit is thought to be limited, as users are exposed to the risk of losing the position and shifting liquid tokens into staked tokens. However, the issue has been raised to ensure it is known to the team and taken to account during future development of <code>StakingThales</code>.</p>
<h3 id="recommendation-1">Recommendation</h3>
<p>The potential for the unstake cooldown period to be bypassed should be considered in any future changes to <code>StakingThales</code> and related contracts that rely on the unstake cooldown period as a security control.</p>
<h3 id="client-response-1">Client response</h3>
<p>Acknowledged by Thales as per design. Furthermore, the attacker would likely lose some amount to margin if they choose this route to fast-track unstaking.</p>
<a name="IO-THL-TBP-003"></a><h2 id="io-thl-tbp-003-no-validation-of-collateral-type-for-live-trades" class="break-before"><strong>IO-THL-TBP-003</strong> No validation of collateral type for live trades</h2>
<table class="metadata">
<tbody>
<tr>
<td class="rating-low">Low</td>
<td class="status-resolved">Resolved</td>
<td><a href="https://github.com/thales-markets/contracts-v2/blob/012072f78e4fdb57db78591036582729e41cb660/contracts/core/StakingThalesBetting/StakingThalesBettingProxy.sol#L87-L91">StakingThalesBettingProxy.sol#L87-L91</a></td>
</tr>
</tbody>
</table>
<p>There is no check in <code>StakingThalesBettingProxy::tradeLive</code> that the <code>_collateral</code> in <code>_liveTradeData</code> is the <code>stakingCollateral</code>, before the trade is submitted. This issue is currently not exploitable, as it would only result in a revert when <code>SportsAMMV2</code> attempts a transfer of the specified collateral from the betting proxy. However, should new features be added to the <code>StakingThalesBettingProxy</code> contract that results in it approving <code>SportsAMMV2</code> for other collateral, it would be possible to create bets using that collateral.</p>
<h3 id="recommendation-2">Recommendation</h3>
<p>Validate that the <code>_collateral</code> in <code>_liveTradeData</code> is the <code>stakingCollateral</code>, and revert if this is not the case.</p>
<h3 id="client-response-2">Client response</h3>
<p>Fixed in <a href="https://github.com/thales-markets/contracts-v2/pull/75/commits/78d5a6b47213c4f272bb17e9da989aae6385b5bb">78d5a6b</a>.</p>
<a name="IO-THL-TBP-004"></a><h2 id="io-thl-tbp-004-merge-account-does-not-check-for-active-tickets-on-source-account" class="break-before"><strong>IO-THL-TBP-004</strong> Merge account does not check for active tickets on source account</h2>
<table class="metadata">
<tbody>
<tr>
<td class="rating-low">Low</td>
<td class="status-closed">Closed</td>
<td><a href="https://github.com/thales-markets/contracts/blob/20c51000f5003d1edfec565d4151030a9219b308/contracts/EscrowAndStaking/StakingThales.sol#L680">StakingThales.sol#L680</a></td>
</tr>
</tbody>
</table>
<p><code>StakingThales::mergeAccount()</code> does not check whether the source account has any existing active tickets in <code>StakingThalesBettingProxy</code> before it allows merging of that account with the specified <code>destAccount</code>. This could result in unintentional loss of funds should those tickets be resolved and winnings distributed to an account that has since been merged with another account.</p>
<h3 id="recommendation-3">Recommendation</h3>
<p><code>StakingThales::mergeAccount()</code> should check whether the source account has any existing active tickets in <code>StakingThalesBettingProxy</code> and revert if this is the case.</p>
<h3 id="client-response-3">Client response</h3>
<p>Won't fix. The current implementation is intentional as <code>StakingThales::mergeAccount()</code> is usually called in high-urgency situations e.g. when a user's private key has been stolen. Thales does not want to block this action while waiting for pending tickets to be resolved.</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>1</td>
<td><a href="https://github.com/thales-markets/contracts/blob/20c51000f5003d1edfec565d4151030a9219b308/contracts/EscrowAndStaking/StakingThales.sol#L319">StakingThales.sol#L319</a></td>
<td>The allowance of THALES set in the <code>StakingThales</code> contract when setting the <code>EscrowThales</code> contract is no longer necessary as the rewards are deposited and pulled from the <code>ThalesStakingRewardsPool</code> contract and not the <code>StakingThales</code> contract. Removing the allowance would mitigate the impact of any potential issues in the <code>EscrowThales</code> that could transfer THALES token from <code>StakingThales</code>.</td>
</tr>
<tr>
<td>2</td>
<td><a href="https://github.com/thales-markets/contracts/blob/20c51000f5003d1edfec565d4151030a9219b308/contracts/EscrowAndStaking/StakingThales.sol">StakingThales.sol</a></td>
<td>To prevent the accumulation of unused storage variables as is currently the case in <code>StakingThales.sol</code>, namespaced storage libraries should be considered for this and other contracts in future development.</td>
</tr>
<tr>
<td>3</td>
<td>General</td>
<td>Defining a common interface for betting proxies that encompasses the common functions in the <code>stakingThalesBettingProxy</code> and <code>FreeBetsHolder</code> would simplify the code in <code>SportsAMMV2</code> and <code>LiveTradingProcessor</code> as it would no longer be necessary to have if/else branches for calling functions such as <code>confirmTicketResolved()</code>. Additionally, this will reduce the number of changes needed for any future betting proxies.</td>
</tr>
<tr>
<td>4</td>
<td><a href="https://github.com/thales-markets/contracts-v2/blob/012072f78e4fdb57db78591036582729e41cb660/contracts/core/StakingThalesBetting/StakingThalesBettingProxy.sol#L34">StakingThalesBettingProxy.sol#L34</a></td>
<td><code>liveRequestsPerUser</code> should be renamed to <code>liveRequestsToUser</code> to be more consistent with the naming scheme of the similar <code>ticketToUser</code> mapping in the contract</td>
</tr>
</tbody>
</table>
<p>These suggestions were communicated to the team resulting in the following:</p>
<ol>
<li>Fixed in <a href="https://github.com/thales-markets/contracts/commit/0f7727dfcac91568b2fc737837382651267f130c">0f7727d</a></li>
<li>Acknowledged and will be taken into account for future development</li>
<li>Fixed in <a href="https://github.com/thales-markets/contracts-v2/commit/027b01741e03441e614365ccfe2a9681366a9a1d">027b017</a></li>
<li>Won't fix to maintain consistency in naming convention with the same variable in the <code>FreeBetsHolder</code> contract.</li>
</ol>
<h1 id="specification">Specification</h1>
<p>The following section outlines the functional changes to the system at a high level as implemented in the codebase. Any perceived points of conflict should be highlighted with the auditing team to determine the source of the discrepancy.</p>
<h2 id="staking-thales-betting-proxy">Staking Thales Betting Proxy</h2>
<p>Thales introduced a new mechanism through which accounts who had staked THALES in the <code>StakingThales</code> contract could use their staked balance to make trades via the <code>SportsAMMV2</code> contract. This was done through the introduction of a new <code>StakingThalesBettingProxy</code> contract which exposed proxy functions to make normal and live trades. This contract bundles the logic of withdrawing the THALES from the staker's balance in <code>StakingThales</code>, creating a trade in <code>SportsAMMV2</code>, keeping records of active and resolved tickets, and depositing any winnings into the staker's balance in <code>StakingThales</code>.</p>
<h2 id="staking-thales-changes">Staking Thales Changes</h2>
<p>Changes were made to the existing <code>StakingThales</code> contract to facilitate the new betting proxy. Primarily, a new <code>_modifyStakingBalance()</code> internal function was introduced to ensure the same accounting logic is applied when staking, unstaking, or buying or redeeming tickets via the <code>StakingThalesBettingProxy</code>.</p>
<h2 id="other-changes">Other Changes</h2>
<p>Several small changes were made to the <code>SportsAMMV2</code> and <code>liveTradingProcessor</code> contracts. These changes introduced new hooks to allow the <code>StakingThalesBettingProxy</code> to make normal and live trades, withdraw the required THALES from <code>StakingThales</code> at the appropriate time, and perform post-ticket resolution housekeeping e.g. deposit any winnings back to <code>StakingThales</code>.</p>
<h1 id="test-coverage-report">Test coverage report</h1>
<p>The coverage report of the provided tests as on the final day of the audit is given below.</p>
<table>
<thead>
<tr>
<th>File</th>
<th>% Stmts</th>
<th>% Branch</th>
<th>% Funcs</th>
<th>% Lines</th>
<th>Uncovered Lines</th>
</tr>
</thead>
<tbody>
<tr>
<td>core/AMM/</td>
<td>99.43</td>
<td>80.39</td>
<td>99.06</td>
<td>99.41</td>
<td></td>
</tr>
<tr>
<td>SportsAMMV2.sol</td>
<td>100</td>
<td>74.32</td>
<td>100</td>
<td>99.54</td>
<td>379</td>
</tr>
<tr>
<td>SportsAMMV2Manager.sol</td>
<td>100</td>
<td>65</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>SportsAMMV2RiskManager.sol</td>
<td>100</td>
<td>92.76</td>
<td>100</td>
<td>99.47</td>
<td>315</td>
</tr>
<tr>
<td>Ticket.sol</td>
<td>95.65</td>
<td>64.29</td>
<td>93.33</td>
<td>98.55</td>
<td>222</td>
</tr>
<tr>
<td>TicketMastercopy.sol</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>core/Data/</td>
<td>100</td>
<td>71.88</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>SportsAMMV2Data.sol</td>
<td>100</td>
<td>76.92</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>SportsAMMV2LiquidityPoolData.sol</td>
<td>100</td>
<td>50</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>core/FreeBets/</td>
<td>98.08</td>
<td>53.23</td>
<td>93.75</td>
<td>97.06</td>
<td></td>
</tr>
<tr>
<td>FreeBetsHolder.sol</td>
<td>98.08</td>
<td>53.23</td>
<td>93.75</td>
<td>97.06</td>
<td>117,159</td>
</tr>
<tr>
<td>core/LiquidityPool/</td>
<td>98.97</td>
<td>78.85</td>
<td>100</td>
<td>98.32</td>
<td></td>
</tr>
<tr>
<td>DefaultLiquidityProvider.sol</td>
<td>100</td>
<td>70</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>SportsAMMV2LiquidityPool.sol</td>
<td>98.91</td>
<td>79.92</td>
<td>100</td>
<td>98.17</td>
<td>... 253,443,520</td>
</tr>
<tr>
<td>SportsAMMV2LiquidityPoolRound.sol</td>
<td>100</td>
<td>50</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>SportsAMMV2LiquidityPoolRoundMastercopy.sol</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>core/LiveTrading/</td>
<td>100</td>
<td>72.22</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>LiveTradingProcessor.sol</td>
<td>100</td>
<td>72.22</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>core/Resolving/</td>
<td>99.22</td>
<td>80</td>
<td>100</td>
<td>98.82</td>
<td></td>
</tr>
<tr>
<td>ChainlinkResolver.sol</td>
<td>97.3</td>
<td>50</td>
<td>100</td>
<td>98.25</td>
<td>139</td>
</tr>
<tr>
<td>SportsAMMV2ResultManager.sol</td>
<td>100</td>
<td>86.67</td>
<td>100</td>
<td>99.12</td>
<td>242</td>
</tr>
<tr>
<td>core/StakingThalesBetting/</td>
<td>100</td>
<td>51.67</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>StakingThalesBettingProxy.sol</td>
<td>100</td>
<td>51.67</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>interfaces/</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>IChainlinkResolver.sol</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>IFreeBetsHolder.sol</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>ILiveTradingProcessor.sol</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>IProxyBetting.sol</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>ISportsAMMV2.sol</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>ISportsAMMV2LiquidityPool.sol</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>ISportsAMMV2Manager.sol</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>ISportsAMMV2ResultManager.sol</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>ISportsAMMV2RiskManager.sol</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>IStakingThalesBettingProxy.sol</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>ITicket.sol</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>IWeth.sol</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>All files</td>
<td>99.34</td>
<td>75.6</td>
<td>99.21</td>
<td>99.09</td>
<td></td>
</tr>
</tbody>
</table>
<p>Overall, the test quality of the smart contracts in scope was comprehensive.</p>
</article>
</main>
</div>