Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating hacks #35

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/.vuepress/config/sidebar-pt.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ module.exports = [
"/exemplos/linguagem-v0.8.3/import.md",
"/exemplos/linguagem-v0.8.3/biblioteca.md",
"/exemplos/linguagem-v0.8.3/hashing-with-keccak256.md",
"/exemplos/linguagem-v0.8.3/verificando-assinatura.md"
"/exemplos/linguagem-v0.8.3/verificando-assinatura.md",
],
},
{
Expand Down Expand Up @@ -127,6 +127,9 @@ module.exports = [
"/exemplos/hacks/manipulacao-do-bloco-timestamp.md",
"/exemplos/hacks/repeticao-de-assinatura.md",
"/exemplos/hacks/ignorar-a-verificacao-do-tamanho-do-contrato.md",
"/exemplos/hacks/implementar-contratos-diferentes-no-mesmo-endereco.md",
"/exemplos/hacks/inflacao-do-cofre.md",
"/exemplos/hacks/licenca-WETH.md",
],
},
{
Expand All @@ -153,7 +156,9 @@ module.exports = [
{
title: "Patterns and Standards",
path: "/evm-maquina-virtual-ethereum/patterns-and-standards",
children: ["/evm-maquina-virtual-ethereum/patterns-and-standards/erc20-and-eip-20.md"],
children: [
"/evm-maquina-virtual-ethereum/patterns-and-standards/erc20-and-eip-20.md",
],
},
],
},
Expand All @@ -171,4 +176,4 @@ module.exports = [
},
],
},
]
];
26 changes: 15 additions & 11 deletions src/exemplos/hacks/acessando-dados-privados.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
# Acessando Dados Privados

#### Vulnerabilidade <a href="#vulnerability" id="vulnerability"></a>
</h4><a href="#vulnerability" id="vulnerability">Vulnerabilidade</a></h4>

Todos os dados num contrato inteligente podem ser lidos.

Vamos ver como podemos ler dados privados. Você vai aprender como Solidity armazena variáveis de estado.
Vamos ver como podemos ler dados privados. No processo, você aprenderá como o Solidity armazena variáveis ​​de estado.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;
pragma solidity ^0.8.20;

/*
Nota: não pode usar web3 on JVM, então use contrato implementado no ropsten
Nota: não pode usar web3 on JVM, então use contrato implementado no Goerli
Nota: browser Web3 é antigo então use Web3 do truffle console

Contrato implantado no Ropsten
0x3505a02BCDFbb225988161a95528bfDb279faD6b
Contract deployed on Goerli
0x534E4Ce0ffF779513793cfd70308AF195827BD31
*/

/*
# Armazenagem
- 2 ** 256 slots
- 32 bytes para cada slot
- dados são armazenados sequencialmente por ordem de declaração
- armazenagem é otimizada para economizar espaço. Se as variáveis vizinhas cabem
- armazenagem é otimizada para economizar espaço. Se as variáveis vizinhas cabem
em 32 bytes, então elas são empacotadas no mesmo slot, começando da direita
*/

Expand Down Expand Up @@ -96,11 +96,11 @@ getArrayLocation(6, 0, 2)
web3.utils.numberToHex("111414077815863400510004064629973595961579173665589224203503662149373724986687")
Nota: Podemos usar também web3 para obter a localização dos dados
web3.utils.soliditySha3({ type: "uint", value: 6 })
1o. usuário
. usuário
web3.eth.getStorageAt("0x3505a02BCDFbb225988161a95528bfDb279faD6b", "0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f", console.log)
web3.eth.getStorageAt("0x3505a02BCDFbb225988161a95528bfDb279faD6b", "0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40", console.log)
Nota: use web3.toAscii para converter bytes32 para alfabeto
2o. usuário
. usuário
web3.eth.getStorageAt("0x3505a02BCDFbb225988161a95528bfDb279faD6b", "0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d41", console.log)
web3.eth.getStorageAt("0x3505a02BCDFbb225988161a95528bfDb279faD6b", "0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d42", console.log)

Expand All @@ -115,6 +115,10 @@ web3.eth.getStorageAt("0x3505a02BCDFbb225988161a95528bfDb279faD6b", "0xb39221ace
*/
```

#### Técnicas preventivas <a href="#preventative-techniques" id="preventative-techniques"></a>
</h4><a href="#preventative-techniques" id="preventative-techniques">Técnicas preventivas</a></h4>

* Não armazene informações confidenciais no blockchain.
- Não armazene informações confidenciais no blockchain.

## Teste no Remix

- [Vault.sol](https://remix.ethereum.org/#code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVApwcmFnbWEgc29saWRpdHkgXjAuOC4yMDsKCi8qCk5vdGE6IG5hbyBwb2RlIHVzYXIgd2ViMyBvbiBKVk0sIGVudGFvIHVzZSBjb250cmF0byBpbXBsZW1lbnRhZG8gbm8gR29lcmxpCk5vdGE6IGJyb3dzZXIgV2ViMyBlIGFudGlnbyBlbnRhbyB1c2UgV2ViMyBkbyB0cnVmZmxlIGNvbnNvbGUKCkNvbnRyYWN0IGRlcGxveWVkIG9uIEdvZXJsaQoweDUzNEU0Q2UwZmZGNzc5NTEzNzkzY2ZkNzAzMDhBRjE5NTgyN0JEMzEKKi8KCi8qCiMgQXJtYXplbmFnZW0KLSAyICoqIDI1NiBzbG90cwotIDMyIGJ5dGVzIHBhcmEgY2FkYSBzbG90Ci0gZGFkb3Mgc2FvIGFybWF6ZW5hZG9zIHNlcXVlbmNpYWxtZW50ZSBwb3Igb3JkZW0gZGUgZGVjbGFyYWNhbwotIGFybWF6ZW5hZ2VtIGUgb3RpbWl6YWRhIHBhcmEgZWNvbm9taXphciBlc3BhY28uIFNlIGFzIHZhcmlhdmVpcyB2aXppbmhhcyBjYWJlbSAKICBlbSAzMiBieXRlcywgZW50YW8gZWxhcyBzYW8gZW1wYWNvdGFkYXMgbm8gbWVzbW8gc2xvdCwgY29tZWNhbmRvIGRhIGRpcmVpdGEKKi8KCmNvbnRyYWN0IFZhdWx0IHsKICAgIC8vIHNsb3QgMAogICAgdWludCBwdWJsaWMgY291bnQgPSAxMjM7CiAgICAvLyBzbG90IDEKICAgIGFkZHJlc3MgcHVibGljIG93bmVyID0gbXNnLnNlbmRlcjsKICAgIGJvb2wgcHVibGljIGlzVHJ1ZSA9IHRydWU7CiAgICB1aW50MTYgcHVibGljIHUxNiA9IDMxOwogICAgLy8gc2xvdCAyCiAgICBieXRlczMyIHByaXZhdGUgcGFzc3dvcmQ7CgogICAgLy8gY29uc3RhbnRlcyBuYW8gdXNhbSBhcm1hemVuYWdlbQogICAgdWludCBwdWJsaWMgY29uc3RhbnQgc29tZUNvbnN0ID0gMTIzOwoKICAgIC8vIHNsb3QgMywgNCwgNSAob25lIGZvciBlYWNoIGFycmF5IGVsZW1lbnQpCiAgICBieXRlczMyWzNdIHB1YmxpYyBkYXRhOwoKICAgIHN0cnVjdCBVc2VyIHsKICAgICAgICB1aW50IGlkOwogICAgICAgIGJ5dGVzMzIgcGFzc3dvcmQ7CiAgICB9CgogICAgLy8gc2xvdCA2IC0gY29tcHJpbWVudG8gZGEgbWF0cml6CiAgICAvL2NvbWVjYW5kbyBkZSBzbG90IGhhc2goNikgLSBlbGVtZW50b3MgZGEgbWF0cml6CiAgICAvLyBzbG90IG9uZGUgbyBlbGVtZW50byBkYSBtYXRyaXogZSBhcm1hemVuYWRvID0ga2VjY2FrMjU2KHNsb3QpKSArIChpbmRleCAqIGVsZW1lbnRTaXplKQogICAgLy8gb25kZSBzbG90ID0gNiBlIGVsZW1lbnRTaXplID0gMiAoMSAodWludCkgKyAgMSAoYnl0ZXMzMikpCiAgICBVc2VyW10gcHJpdmF0ZSB1c2VyczsKCiAgICAvLyBzbG90IDcgLSB2YXppbwogICAgLy8gZW50cmFkYXMgc2FvIGFybWF6ZW5hZGFzIG5vIGhhc2goa2V5LCBzbG90KQogICAgLy8gb25kZSBzbG90ID0gNywga2V5ID0gbWFwIGtleQogICAgbWFwcGluZyh1aW50ID0+IFVzZXIpIHByaXZhdGUgaWRUb1VzZXI7CgogICAgY29uc3RydWN0b3IoYnl0ZXMzMiBfcGFzc3dvcmQpIHsKICAgICAgICBwYXNzd29yZCA9IF9wYXNzd29yZDsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGRVc2VyKGJ5dGVzMzIgX3Bhc3N3b3JkKSBwdWJsaWMgewogICAgICAgIFVzZXIgbWVtb3J5IHVzZXIgPSBVc2VyKHtpZDogdXNlcnMubGVuZ3RoLCBwYXNzd29yZDogX3Bhc3N3b3JkfSk7CgogICAgICAgIHVzZXJzLnB1c2godXNlcik7CiAgICAgICAgaWRUb1VzZXJbdXNlci5pZF0gPSB1c2VyOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldEFycmF5TG9jYXRpb24oCiAgICAgICAgdWludCBzbG90LAogICAgICAgIHVpbnQgaW5kZXgsCiAgICAgICAgdWludCBlbGVtZW50U2l6ZQogICAgKSBwdWJsaWMgcHVyZSByZXR1cm5zICh1aW50KSB7CiAgICAgICAgcmV0dXJuIHVpbnQoa2VjY2FrMjU2KGFiaS5lbmNvZGVQYWNrZWQoc2xvdCkpKSArIChpbmRleCAqIGVsZW1lbnRTaXplKTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRNYXBMb2NhdGlvbih1aW50IHNsb3QsIHVpbnQga2V5KSBwdWJsaWMgcHVyZSByZXR1cm5zICh1aW50KSB7CiAgICAgICAgcmV0dXJuIHVpbnQoa2VjY2FrMjU2KGFiaS5lbmNvZGVQYWNrZWQoa2V5LCBzbG90KSkpOwogICAgfQp9CgovKgpzbG90IDAgLSBjb3VudAp3ZWIzLmV0aC5nZXRTdG9yYWdlQXQoIjB4MzUwNWEwMkJDREZiYjIyNTk4ODE2MWE5NTUyOGJmRGIyNzlmYUQ2YiIsIDAsIGNvbnNvbGUubG9nKQpzbG90IDEgLSB1MTYsIGlzVHJ1ZSwgb3duZXIKd2ViMy5ldGguZ2V0U3RvcmFnZUF0KCIweDM1MDVhMDJCQ0RGYmIyMjU5ODgxNjFhOTU1MjhiZkRiMjc5ZmFENmIiLCAxLCBjb25zb2xlLmxvZykKc2xvdCAyIC0gcGFzc3dvcmQKd2ViMy5ldGguZ2V0U3RvcmFnZUF0KCIweDM1MDVhMDJCQ0RGYmIyMjU5ODgxNjFhOTU1MjhiZkRiMjc5ZmFENmIiLCAyLCBjb25zb2xlLmxvZykKCnNsb3QgNiAtIGFycmF5IGxlbmd0aApnZXRBcnJheUxvY2F0aW9uKDYsIDAsIDIpCndlYjMudXRpbHMubnVtYmVyVG9IZXgoIjExMTQxNDA3NzgxNTg2MzQwMDUxMDAwNDA2NDYyOTk3MzU5NTk2MTU3OTE3MzY2NTU4OTIyNDIwMzUwMzY2MjE0OTM3MzcyNDk4NjY4NyIpCk5vdGE6IFBvZGVtb3MgdXNhciB0YW1iZW0gd2ViMyBwYXJhIG9idGVyIGEgbG9jYWxpemFjYW8gZG9zIGRhZG9zCndlYjMudXRpbHMuc29saWRpdHlTaGEzKHsgdHlwZTogInVpbnQiLCB2YWx1ZTogNiB9KQoxui4gdXN1YXJpbwp3ZWIzLmV0aC5nZXRTdG9yYWdlQXQoIjB4MzUwNWEwMkJDREZiYjIyNTk4ODE2MWE5NTUyOGJmRGIyNzlmYUQ2YiIsICIweGY2NTIyMjIzMTNlMjg0NTk1MjhkOTIwYjY1MTE1YzE2YzA0ZjNlZmM4MmFhZWRjOTdiZTU5ZjNmMzc3YzBkM2YiLCBjb25zb2xlLmxvZykKd2ViMy5ldGguZ2V0U3RvcmFnZUF0KCIweDM1MDVhMDJCQ0RGYmIyMjU5ODgxNjFhOTU1MjhiZkRiMjc5ZmFENmIiLCAiMHhmNjUyMjIyMzEzZTI4NDU5NTI4ZDkyMGI2NTExNWMxNmMwNGYzZWZjODJhYWVkYzk3YmU1OWYzZjM3N2MwZDQwIiwgY29uc29sZS5sb2cpCk5vdGE6IHVzZSB3ZWIzLnRvQXNjaWkgcGFyYSBjb252ZXJ0ZXIgYnl0ZXMzMiBwYXJhIGFsZmFiZXRvCjK6LiB1c3VhcmlvCndlYjMuZXRoLmdldFN0b3JhZ2VBdCgiMHgzNTA1YTAyQkNERmJiMjI1OTg4MTYxYTk1NTI4YmZEYjI3OWZhRDZiIiwgIjB4ZjY1MjIyMjMxM2UyODQ1OTUyOGQ5MjBiNjUxMTVjMTZjMDRmM2VmYzgyYWFlZGM5N2JlNTlmM2YzNzdjMGQ0MSIsIGNvbnNvbGUubG9nKQp3ZWIzLmV0aC5nZXRTdG9yYWdlQXQoIjB4MzUwNWEwMkJDREZiYjIyNTk4ODE2MWE5NTUyOGJmRGIyNzlmYUQ2YiIsICIweGY2NTIyMjIzMTNlMjg0NTk1MjhkOTIwYjY1MTE1YzE2YzA0ZjNlZmM4MmFhZWRjOTdiZTU5ZjNmMzc3YzBkNDIiLCBjb25zb2xlLmxvZykKCnNsb3QgNyAtIGVtcHR5CmdldE1hcExvY2F0aW9uKDcsIDEpCndlYjMudXRpbHMubnVtYmVyVG9IZXgoIjgxMjIyMTkxOTg2MjI2ODA5MTAzMjc5MTE5OTk0NzA3ODY4MzIyODU1NzQxODE5OTA1OTA0NDE3OTUzMDkyNjY2Njk5MDk2OTYzMTEyIikKTm90YTogTm9zIHBvZGVtb3MgdXNhciB3ZWIzIHBhcmEgb2J0ZXIgYSBsb2NhbGl6YWNhbyBkb3MgZGFkb3MKd2ViMy51dGlscy5zb2xpZGl0eVNoYTMoeyB0eXBlOiAidWludCIsIHZhbHVlOiAxIH0sIHt0eXBlOiAidWludCIsIHZhbHVlOiA3fSkKdXNlciAxCndlYjMuZXRoLmdldFN0b3JhZ2VBdCgiMHgzNTA1YTAyQkNERmJiMjI1OTg4MTYxYTk1NTI4YmZEYjI3OWZhRDZiIiwgIjB4YjM5MjIxYWNlMDUzNDY1ZWMzNDUzY2UyYjM2NDMwYmQxMzhiOTk3ZWNlYTI1YzEwNDNkYTBjMzY2ODEyYjgyOCIsIGNvbnNvbGUubG9nKQp3ZWIzLmV0aC5nZXRTdG9yYWdlQXQoIjB4MzUwNWEwMkJDREZiYjIyNTk4ODE2MWE5NTUyOGJmRGIyNzlmYUQ2YiIsICIweGIzOTIyMWFjZTA1MzQ2NWVjMzQ1M2NlMmIzNjQzMGJkMTM4Yjk5N2VjZWEyNWMxMDQzZGEwYzM2NjgxMmI4MjkiLCBjb25zb2xlLmxvZykKKi8=&version=soljson-v0.8.20+commit.a1b79de6.js)
17 changes: 11 additions & 6 deletions src/exemplos/hacks/autodestruicao.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# Autodestruição

Contratos podem ser apagados do blockchain chamando `selfdestruct`.
Os contratos podem ser apagados do blockchain chamando `selfdestruct`.

`selfdestruct` envia todo Ether restante armazenado no contrato para o endereço designado.

#### Vulnerabilidade <a href="#vulnerability" id="vulnerability"></a>
</h4><a href="#vulnerability" id="vulnerability">Vulnerabilidade</a></h4>

Um contrato malicioso pode usar `selfdestruct` para forçar o envio de Ether para qualquer contrato.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;
pragma solidity ^0.8.20;

// A meta deste jogo é ser o 7o. jogador a depositar 1 Ether.
// Jogadores podem depositar somente 1 Ether de cada vez.
Expand Down Expand Up @@ -69,13 +69,13 @@ contract Attack {
}
```

#### Técnicas preventivas <a href="#preventative-techniques" id="preventative-techniques"></a>
</h4><a href="#preventative-techniques" id="preventative-techniques">Técnicas preventivas</a></h4>

`Não conte com` `address(this).balance`
Não confie em `address(this).balance`

```
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;
pragma solidity ^0.8.20;

contract EtherGame {
uint public targetAmount = 3 ether;
Expand All @@ -101,3 +101,8 @@ contract EtherGame {
}
}
```

## Teste no Remix

- [ForceEther.sol](https://remix.ethereum.org/#code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVApwcmFnbWEgc29saWRpdHkgXjAuOC4yMDsKCi8vIEEgbWV0YSBkZXN0ZSBqb2dvIGUgc2VyIG8gN28uIGpvZ2Fkb3IgYSBkZXBvc2l0YXIgMSBFdGhlci4KLy8gSm9nYWRvcmVzIHBvZGVtIGRlcG9zaXRhciBzb21lbnRlIDEgRXRoZXIgZGUgY2FkYSB2ZXouCi8vIE8gdmVuY2Vkb3Igc2VyYSBjYXBheiBkZSByZXRpcmFyIHRvZG8gRXRoZXIuCgovKgoxLiBJbXBsZW1lbnRlIEV0aGVyR2FtZQoyLiBKb2dhZG9yZXMgKHZhbW9zIGRpemVyIEFsaWNlIGUgQm9iKSBkZWNpZGVtIGpvZ2FyLCBkZXBvc2l0YW0gMSBFdGhlciBjYWRhLgoyLiBJbXBsZW1lbnRlIEF0dGFjayBjb20gZW5kZXJlY28gZG8gRXRoZXJHYW1lCjMuIENoYW1lIEF0dGFjay5hdHRhY2sgZW52aWFuZG8gNSBldGhlci4gSXNzbyBxdWVicmFyYSBvIGpvZ28uCiAgIE5pbmd1ZW0gcG9kZSBzZSB0b3JuYXIgY2FtcGVhby4KCk8gcXVlIGFjb250ZWNldT8KQXR0YWNrIGZvcmNvdSBvIGJhbGFuY28gZG8gRXRoZXJHYW1lIHBhcmEgNyBldGhlci4KQWdvcmEgbmluZ3VlbSBwb2RlIGRlcG9zaXRhciBlIG5hbyBzZSBwb2RlIGVzdGFiZWxlY2VyIHVtIGNhbXBlYW8uCiovCgpjb250cmFjdCBFdGhlckdhbWUgewogICAgdWludCBwdWJsaWMgdGFyZ2V0QW1vdW50ID0gNyBldGhlcjsKICAgIGFkZHJlc3MgcHVibGljIHdpbm5lcjsKCiAgICBmdW5jdGlvbiBkZXBvc2l0KCkgcHVibGljIHBheWFibGUgewogICAgICAgIHJlcXVpcmUobXNnLnZhbHVlID09IDEgZXRoZXIsICJZb3UgY2FuIG9ubHkgc2VuZCAxIEV0aGVyIik7CgogICAgICAgIHVpbnQgYmFsYW5jZSA9IGFkZHJlc3ModGhpcykuYmFsYW5jZTsKICAgICAgICByZXF1aXJlKGJhbGFuY2UgPD0gdGFyZ2V0QW1vdW50LCAiR2FtZSBpcyBvdmVyIik7CgogICAgICAgIGlmIChiYWxhbmNlID09IHRhcmdldEFtb3VudCkgewogICAgICAgICAgICB3aW5uZXIgPSBtc2cuc2VuZGVyOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBjbGFpbVJld2FyZCgpIHB1YmxpYyB7CiAgICAgICAgcmVxdWlyZShtc2cuc2VuZGVyID09IHdpbm5lciwgIk5vdCB3aW5uZXIiKTsKCiAgICAgICAgKGJvb2wgc2VudCwgKSA9IG1zZy5zZW5kZXIuY2FsbHt2YWx1ZTogYWRkcmVzcyh0aGlzKS5iYWxhbmNlfSgiIik7CiAgICAgICAgcmVxdWlyZShzZW50LCAiRmFpbGVkIHRvIHNlbmQgRXRoZXIiKTsKICAgIH0KfQoKY29udHJhY3QgQXR0YWNrIHsKICAgIEV0aGVyR2FtZSBldGhlckdhbWU7CgogICAgY29uc3RydWN0b3IoRXRoZXJHYW1lIF9ldGhlckdhbWUpIHsKICAgICAgICBldGhlckdhbWUgPSBFdGhlckdhbWUoX2V0aGVyR2FtZSk7CiAgICB9CgogICAgZnVuY3Rpb24gYXR0YWNrKCkgcHVibGljIHBheWFibGUgewogICAgICAgIC8vIFZvY2UgcG9kZSBzaW1wbGVzbWVudGUgcXVlYnJhciBvIGpvZ28gZW52aWFuZG8gZXRoZXIgZGUgZm9ybWEgcXVlCiAgICAgICAgLy8gbyBzYWxkbyBkbyBqb2dvID49IDcgZXRoZXIKCiAgICAgICAgLy8gbGFuY2UgYWRkcmVzcyBhIHBhZ2FyCiAgICAgICAgYWRkcmVzcyBwYXlhYmxlIGFkZHIgPSBwYXlhYmxlKGFkZHJlc3MoZXRoZXJHYW1lKSk7CiAgICAgICAgc2VsZmRlc3RydWN0KGFkZHIpOwogICAgfQp9&version=soljson-v0.8.20+commit.a1b79de6.js)
- [PreventForceEther.sol](https://remix.ethereum.org/#code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVApwcmFnbWEgc29saWRpdHkgXjAuOC4yMDsKCmNvbnRyYWN0IEV0aGVyR2FtZSB7CiAgICB1aW50IHB1YmxpYyB0YXJnZXRBbW91bnQgPSAzIGV0aGVyOwogICAgdWludCBwdWJsaWMgYmFsYW5jZTsKICAgIGFkZHJlc3MgcHVibGljIHdpbm5lcjsKCiAgICBmdW5jdGlvbiBkZXBvc2l0KCkgcHVibGljIHBheWFibGUgewogICAgICAgIHJlcXVpcmUobXNnLnZhbHVlID09IDEgZXRoZXIsICJZb3UgY2FuIG9ubHkgc2VuZCAxIEV0aGVyIik7CgogICAgICAgIGJhbGFuY2UgKz0gbXNnLnZhbHVlOwogICAgICAgIHJlcXVpcmUoYmFsYW5jZSA8PSB0YXJnZXRBbW91bnQsICJHYW1lIGlzIG92ZXIiKTsKCiAgICAgICAgaWYgKGJhbGFuY2UgPT0gdGFyZ2V0QW1vdW50KSB7CiAgICAgICAgICAgIHdpbm5lciA9IG1zZy5zZW5kZXI7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGNsYWltUmV3YXJkKCkgcHVibGljIHsKICAgICAgICByZXF1aXJlKG1zZy5zZW5kZXIgPT0gd2lubmVyLCAiTm90IHdpbm5lciIpOwoKICAgICAgICAoYm9vbCBzZW50LCApID0gbXNnLnNlbmRlci5jYWxse3ZhbHVlOiBiYWxhbmNlfSgiIik7CiAgICAgICAgcmVxdWlyZShzZW50LCAiRmFpbGVkIHRvIHNlbmQgRXRoZXIiKTsKICAgIH0KfQ==&version=soljson-v0.8.20+commit.a1b79de6.js)
Loading