diff --git a/client/src/gamedata/tr/descriptions/levels/denial.md b/client/src/gamedata/tr/descriptions/levels/denial.md new file mode 100644 index 000000000..a91251fcb --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/denial.md @@ -0,0 +1,3 @@ +Bu, zaman içinde yavaş yavaş fon akıtan basit bir cüzdan. Para çekme ortağı (withdrawing partner) olarak yavaş yavaş fonları çekebilirsin. + +Eğer sahibin `withdraw()`'ı çağırdığında fonları çekmesini engelleyebilirsen (kontratın hala fonları varken ve transfer 1M gas veya daha altındayken) bu seviyeyi geçersin. \ No newline at end of file diff --git a/client/src/gamedata/tr/descriptions/levels/denial_complete.md b/client/src/gamedata/tr/descriptions/levels/denial_complete.md new file mode 100644 index 000000000..e1a9a4bd0 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/denial_complete.md @@ -0,0 +1,8 @@ +Bu seviye, sabit bir gas miktarı belirtilmediğinde bilinmeyen dış kontrat çağrılarının hâlâ hizmet engelleme (DoS) saldırı vektörleri yaratabileceğini gösterir. + +Eğer bir dış çağrı revert ettiğinde işlem akışına devam etmek için low-level `call` kullanıyorsan, mutlaka sabit bir gas ödeneği (gas stipend) belirt. Örneğin: `call.gas(100000).value()`. + +Genellikle re-entrancy saldırılarını önlemek için [checks-effects-interactions](http://solidity.readthedocs.io/en/latest/security-considerations.html#use-the-checks-effects-interactions-pattern) desenini izlemelisin, ancak fonksiyonun sonunda birden fazla dış çağrı yapılması gibi başka durumlarda da benzer sorunlar ortaya çıkabilir. + +*Not*: Bir dış `CALL`, o an kullanılabilir gazın en fazla 63/64 oranını kullanabilir. +Bu yüzden, tamamlanması gereken opcode’lar için kalan gaz miktarına bağlı olarak, yeterince yüksek gazlı bir işlem (yani kalan 1/64’lük gazın üst düzey çağrıyı tamamlayabilecek kadar olduğu bir işlem) bu özel saldırıya karşı bir dereceye kadar korunma sağlayabilir. \ No newline at end of file diff --git a/client/src/gamedata/tr/descriptions/levels/dex.md b/client/src/gamedata/tr/descriptions/levels/dex.md new file mode 100644 index 000000000..0ed887e4f --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/dex.md @@ -0,0 +1,18 @@ +Bu seviyenin amacı, aşağıdaki basit [DEX](https://en.wikipedia.org/wiki/Decentralized_exchange) kontratını fiyat manipülasyonu ile hacklemen ve fonları çalman. + +10 adet `token1` ve 10 adet `token2` ile başlayacaksın. DEX kontratı ise iki tokenden de 100 adet ile başlıyor. + +Eğer sözleşmeden en az birini (token1 ya da token2) tamamen boşaltmayı başarıp sözleşmenin varlıkların “kötü” bir fiyatını raporlamasına yol açarsan, bu seviyeyi geçersin. + +  +### Kısa not +Normalde bir ERC20 token ile swap yaparken sözleşmenin token’larını harcayabilmesi için önce `approve` etmen gerekir. Oyunun sözdizimine uyması için biz DEX kontratına `approve` metodunu ekledik. Yani token kontratlarını doğrudan çağırmak yerine şu komutu kullanabilirsin: `contract.approve(contract.address, )`. Bu, iki token için de istenen miktarda onay verecektir.`SwappableToken` kontratını ayrıca inceleyebilirsin ama zorunda değilsin. + +  +Yardımcı olabilecek noktalar: +* Token fiyatı nasıl hesaplanıyor? +* `swap` metodu nasıl çalışıyor? +* Bir ERC20 işlemini `approve` ile nasıl onaylarsın? +* Bir kontratla etkileşmenin birden fazla yolu vardır! +* Remix yardımcı olabilir. +* "At Address" ne işe yarar? diff --git a/client/src/gamedata/tr/descriptions/levels/dex2.md b/client/src/gamedata/tr/descriptions/levels/dex2.md new file mode 100644 index 000000000..4c2d40c98 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/dex2.md @@ -0,0 +1,9 @@ +Bu seviye, bir önceki seviyedeki `Dex` kontratının ince şekilde değiştirilmiş bir versiyonu olan `DexTwo`’yu farklı bir yöntemle çökertmeni isteyecek. + +Başarılı olmak için `DexTwo` kontratındaki token1 ve token2 bakiyelerini tamamen boşaltman gerekiyor. + +Başlangıçta yine `token1`’den 10, `token2`’den 10 token ile başlıyorsun. DEX kontratı hâlâ her iki tokenden de 100 ile başlıyor. + +  +Yardımcı olabilecek noktalar: +* `swap` metodu nasıl değiştirilmiş? diff --git a/client/src/gamedata/tr/descriptions/levels/dex2_complete.md b/client/src/gamedata/tr/descriptions/levels/dex2_complete.md new file mode 100644 index 000000000..1c96df2fe --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/dex2_complete.md @@ -0,0 +1,9 @@ +Gördüğümüz gibi, kontratlar arasındaki etkileşim beklenmedik davranışların kaynağı olabilir. + +Bir kontratın [ERC20 standardını](https://eips.ethereum.org/EIPS/eip-20) uyguladığını iddia etmesi onun güvenilir olduğu anlamına gelmez. + +Bazı tokenler, `transfer` metodlarından boolean değer döndürmeyerek ERC20 standardından sapar. Detaylar için: [Missing return value bug - At least 130 tokens affected](https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca). + +Diğer ERC20 tokenleri, özellikle kötü niyetli kişiler tarafından tasarlanmış olanlar, daha zararlı davranabilir. + +Eğer bir DEX tasarlıyorsan ve herhangi biri kendi tokenlerini merkezi bir otoritenin izni olmadan listeleyebiliyorsa, DEX’in doğruluğu DEX kontratı ile işlem gören token kontratlarının etkileşimine bağlı olacaktır. \ No newline at end of file diff --git a/client/src/gamedata/tr/descriptions/levels/dex_complete.md b/client/src/gamedata/tr/descriptions/levels/dex_complete.md new file mode 100644 index 000000000..23afd4fb7 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/dex_complete.md @@ -0,0 +1,57 @@ +Tam sayı matematiğini bir kenara bırakacak olursak, herhangi bir kaynaktan fiyat veya veri almak, akıllı sözleşmeler için devasa bir saldırı vektörü oluşturur. + +Bu örnekten de görebileceğiniz gibi, çok sermayesi olan biri fiyatı tek hamlede manipüle edebilir ve buna bağlı çalışan tüm uygulamalar yanlış fiyat kullanabilir. + +Borsa kendi başına merkeziyetsiz olsa da, varlığın fiyatı merkezidir çünkü tek bir DEX’ten gelir. Ancak, gerçek varlıkları temsil eden token’lar söz konusu olduğunda, çoğu token birden fazla DEX ve ağda işlem çiftine sahiptir. Bu durum, spesifik bir DEX hedef alındığında varlık fiyatı üzerindeki etkiyi azaltır. + +[Oracle'lar](https://betterprogramming.pub/what-is-a-blockchain-oracle-f5ccab8dbd72?source=friends_link&sk=d921a38466df8a9176ed8dd767d8c77d) akıllı sözleşmelere veri girişi ve çıkışı sağlamak için kullanılır. + +[Chainlink Data Feeds](https://docs.chain.link/docs/get-the-latest-price) merkeziyetsiz verileri akıllı sözleşmelerinize taşımak için kullanılan güvenli ve güvenilir bir yoldur. Çok çeşitli kaynaklardan veri alabilir, [güvenli rastgelelik](https://docs.chain.link/docs/chainlink-vrf), [herhangi bir API çağrısı](https://docs.chain.link/docs/make-a-http-get-request) yapabilme, [modüler oracle ağı oluşturma](https://docs.chain.link/docs/architecture-decentralized-model), [bakım/izleme (upkeep), eylemler ve yönetim imkanları](https://docs.chain.link/docs/kovan-keeper-network-beta) ile sınırsız özelleştirme olanağı da sunar. + +[Uniswap TWAP Oracles](https://docs.uniswap.org/contracts/v2/concepts/core-concepts/oracles) ise zaman ağırlıklı ortalama fiyat [TWAP](https://en.wikipedia.org/wiki/Time-weighted_average_price#) modeline dayanır. Bu tasarım cazip olabilir, ancak protokol büyük ölçüde DEX likiditesine bağımlıdır; likidite düşükse fiyatlar kolayca manipüle edilebilir. + +Aşağıda, Sepolia testnet üzerinde Chainlink veri kaynağından Bitcoin’in USD fiyatını alma örneği bulunuyor: + +``` +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.7; + +import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; + +contract PriceConsumerV3 { + AggregatorV3Interface internal priceFeed; + + /** + * Network: Sepolia + * Aggregator: BTC/USD + * Address: 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43 + */ + constructor() { + priceFeed = AggregatorV3Interface( + 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43 + ); + } + + /** + * Returns the latest price. + */ + function getLatestPrice() public view returns (int) { + // prettier-ignore + ( + /* uint80 roundID */, + int price, + /*uint startedAt*/, + /*uint timeStamp*/, + /*uint80 answeredInRound*/ + ) = priceFeed.latestRoundData(); + return price; + } +} + +``` +[Remix'te dene](https://remix.ethereum.org/#url=https://docs.chain.link/samples/PriceFeeds/PriceConsumerV3.sol) + +Chainlink veri kaynağı [sayfasını](https://data.chain.link/ethereum/mainnet/crypto-usd/btc-usd) kontrol ederek Bitcoin fiyatının 31 farklı kaynaktan sorgulandığını görebilirsiniz. + +Ayrıca, tüm Chainlink fiyat beslemelerinin adreslerinin [listesini](https://docs.chain.link/data-feeds/price-feeds/addresses/) de inceleyebilirsiniz. + diff --git a/client/src/gamedata/tr/descriptions/levels/doubleentrypoint.md b/client/src/gamedata/tr/descriptions/levels/doubleentrypoint.md new file mode 100644 index 000000000..2ba4e715b --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/doubleentrypoint.md @@ -0,0 +1,10 @@ +Bu seviye, özel bir işlevi olan bir `CryptoVault` kontratını içeriyor, `sweepToken` fonksiyonu. Bu, kontratta sıkışan token’ları almak için yaygın olarak kullanılan bir fonksiyondur. `CryptoVault` silinemeyecek (sweeping yapılamayacak) bir `underlying` token ile çalışır; çünkü bu token `CryptoVault`'un temel mantığının önemli bir parçasıdır. Diğer tüm token’lar ise alınabilir (sweep yapılabilir). + +Underlying token, `DoubleEntryPoint` kontratında tanımlı DET token örneğidir ve `CryptoVault` içinde 100 birim bulunur. Buna ek olarak, `CryptoVault` içinde 100 birim `LegacyToken LGT` da vardır. + +Bu seviyede, `CryptoVault`’daki hatayı bulmalı ve token’ların çekilmesini engelleyecek bir çözüm geliştirmelisin. + +Kontrat ayrıca bir `Forta` kontratına sahiptir; buraya herhangi bir kullanıcı kendi `detection bot` kontratını kaydedebilir. Forta; DeFi, NFT, governance, köprüler ve diğer Web3 sistemlerindeki tehditleri ve anormallikleri olabildiğince hızlı tespit etmek için merkeziyetsiz ve topluluk tabanlı bir izleme ağıdır. Senin görevin bir `detection bot` uygulamak ve bunu `Forta` kontratına kaydetmektir. Bot, potansiyel saldırıları veya hata istismarlarını önlemek için doğru uyarıları oluşturacak şekilde çalışmalıdır. + +Yardımcı olabilecek noktalar: +- Bir token kontratı için double entry point nasıl çalışır? diff --git a/client/src/gamedata/tr/descriptions/levels/doubleentrypoint_complete.md b/client/src/gamedata/tr/descriptions/levels/doubleentrypoint_complete.md new file mode 100644 index 000000000..aeaff4648 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/doubleentrypoint_complete.md @@ -0,0 +1,13 @@ +Tebrikler! + +Bu, bir [Forta bot](https://docs.forta.network/en/latest/) ile ilk deneyimin. + +Forta, bağımsız node operatörlerinden oluşan merkeziyetsiz bir ağdır ve tüm işlemleri ile blok blok durum değişikliklerini olağan dışı işlemler ve tehditler açısından tarar. Bir sorun tespit edildiğinde, node operatörleri potansiyel riskler hakkında abonelere uyarılar gönderir; bu sayede kullanıcılar gerekli aksiyonları alabilir. + +Buradaki örnek yalnızca eğitim amaçlıdır çünkü Forta botları henüz akıllı kontratlara entegre edilmemiştir. Forta’da bir bot, belirli koşulları veya olayları tespit eden bir kod scriptidir; uyarı yayımlandığında otomatik bir işlem tetiklemez - en azından şimdilik. Bu seviyede botun uyarısı, Forta'nın amaçlanan bot tasarımından farklı olarak, işlemde etkili bir şekilde geri dönüşü (revert) tetikler. + +Detection botları, kontratların son implementasyonlarına çok bağlıdır ve bazıları yükseltilebilir olduğundan bot entegrasyonlarını bozabilir ama bunu önlemek için kontrat yükseltmelerini takip eden ve bu durumlara tepki veren özel bir bot oluşturmak da mümkündür. Nasıl yapılacağını [buradan](https://docs.forta.network/en/latest/quickstart/) öğrenebilirsin. + +Ayrıca, OpenZeppelin’in [Compound protokolü ile yaptığı son işbirliği](https://compound.finance/governance/proposals/76) sırasında ortaya çıkan güncel bir güvenlik sorununu da geçtiğinizi belirtelim. + +Double entry point özelliğine sahip token’lar, birçok protokolü etkileyebilecek karmaşık bir yapıdır. Çünkü genellikle her token için yalnızca bir kontrat olduğu varsayılır. Ama bu sefer durum farklıydı :) Neler olduğuna tüm detaylarıyla [buradan](https://blog.openzeppelin.com/compound-tusd-integration-issue-retrospective/) ulaşabilirsin. diff --git a/client/src/gamedata/tr/descriptions/levels/elevator.md b/client/src/gamedata/tr/descriptions/levels/elevator.md new file mode 100644 index 000000000..71d148d63 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/elevator.md @@ -0,0 +1,5 @@ +Bu asansör binanın tepesine ulaşmana izin vermeyecek. Değil mi? + +##### Yardımcı olabilecek noktalar: +* Bazen solidity, verdiği sözleri tutmakta pek iyi değildir. +* Bu `Elevator (asansör)`, bir `Building (bina)` içinden kullanılmak üzere tasarlanmıştır. \ No newline at end of file diff --git a/client/src/gamedata/tr/descriptions/levels/elevator_complete.md b/client/src/gamedata/tr/descriptions/levels/elevator_complete.md new file mode 100644 index 000000000..a42a578c3 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/elevator_complete.md @@ -0,0 +1,5 @@ +Bir arayüzde `view` fonksiyon belirleyicisini kullanarak durum (state) değişikliklerini önleyebilirsin. `pure` değiştiricisi de fonksiyonların durumu değiştirmesini engeller. +[Solidity dokümantasyonunu](http://solidity.readthedocs.io/en/develop/contracts.html#view-functions) mutlaka oku ve bu konudaki ince noktaları öğren. + +Bu seviyeyi çözmenin alternatif bir yolu da, girdiye (input) bağlı olarak farklı sonuçlar döndüren fakat durumu değiştirmeyen bir view fonksiyonu yazmaktır, örneğin `gasleft()`. + diff --git a/client/src/gamedata/tr/descriptions/levels/gatekeeper1.md b/client/src/gamedata/tr/descriptions/levels/gatekeeper1.md new file mode 100644 index 000000000..d63e2e762 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/gatekeeper1.md @@ -0,0 +1,5 @@ +Bu seviyeyi geçmek için bekçiyi (gatekeeper) atlatmalı ve katılımcı olarak kaydolmalısın. + +##### Yardımcı olabilecek noktalar: +* Telephone ve Token seviyelerinde öğrendiklerini hatırla. +* Solidity dokümantasyonundaki özel fonksiyon `gasleft()` hakkında daha fazla bilgi edinebilirsin ([Units and Global Variables](https://docs.soliditylang.org/en/v0.8.3/units-and-global-variables.html) ve [External Function Calls](https://docs.soliditylang.org/en/v0.8.3/control-structures.html#external-function-calls)). diff --git a/client/src/gamedata/tr/descriptions/levels/gatekeeper1_complete.md b/client/src/gamedata/tr/descriptions/levels/gatekeeper1_complete.md new file mode 100644 index 000000000..006f9d3da --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/gatekeeper1_complete.md @@ -0,0 +1 @@ +Tebrikler! Şimdi ikinci bekçiyi aşmayı dene bakalım... diff --git a/client/src/gamedata/tr/descriptions/levels/gatekeeper2.md b/client/src/gamedata/tr/descriptions/levels/gatekeeper2.md new file mode 100644 index 000000000..62d614227 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/gatekeeper2.md @@ -0,0 +1,6 @@ +Bu bekçi seni biraz daha zorlayacak yeni engellerle tanıştırıyor. Bu seviyeyi geçmek için katılımcı olarak kaydolman gerekiyor. + +##### Yardımcı olabilecek noktalar: +* İlk bekçiden geçerken öğrendiklerini hatırla — çünkü ilk kapı tamamen aynı. +* İkinci kapıdaki `assembly` anahtar kelimesi, Solidity’nin kendi sözdiziminin ötesinde düşük seviyeli (low-level) fonksiyonlara erişmeni sağlar. Daha fazla bilgi için [Solidity Assembly](http://solidity.readthedocs.io/en/v0.4.23/assembly.html) sayfasına göz at. Bu kapıda kullanılan `extcodesize` komutu, belirli bir adresteki sözleşme kodunun boyutunu döndürür - bu değerin ne zaman ve nasıl ayarlandığını anlamak için [yellow paper](https://ethereum.github.io/yellowpaper/paper.pdf)'ın 7. bölümüne bakabilirsin. +* Üçüncü kapıda kullanılan `^` karakteri bir bit düzeyinde XOR (özel veya) işlemidir ve burada bir başka yaygın bit düzeyi işlemini uygulamak için kullanılmıştır. ([Solidity cheatsheet](http://solidity.readthedocs.io/en/v0.4.23/miscellaneous.html#cheatsheet)'e göz at). Ayrıca Coin Flip seviyesi de bu meydan okumaya hazırlanmak için iyi bir başlangıç noktasıdır. \ No newline at end of file diff --git a/client/src/gamedata/tr/descriptions/levels/gatekeeper2_complete.md b/client/src/gamedata/tr/descriptions/levels/gatekeeper2_complete.md new file mode 100644 index 000000000..7f008c8c2 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/gatekeeper2_complete.md @@ -0,0 +1,2 @@ +Harika gidiyorsun! Artık bekçiyi geçebildiğine göre, Ethereum mainnet üzerindeki [theCyber](https://etherscan.io/address/thecyber.eth#code), adlı merkeziyetsiz kulübe katılacak yeteneğe sahipsin. Bir şifre (passphrase) almak için kulüp başkanıyla [reddit](https://www.reddit.com/user/0age) veya [email](mailto:0age@protonmail.com) üzerinden iletişime geç. Ardından şifreyi kullanarak sözleşmeye [gatekeepertwo.thecyber.eth](https://etherscan.io/address/gatekeepertwo.thecyber.eth#code) üzerinden kaydol. (Sözleşme yalnızca ilk 128 katılımcıyı kabul ediyor). + diff --git a/client/src/gamedata/tr/descriptions/levels/gatekeeper3.md b/client/src/gamedata/tr/descriptions/levels/gatekeeper3.md new file mode 100644 index 000000000..64d051d36 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/gatekeeper3.md @@ -0,0 +1,6 @@ +Kapıları aş ve bir katılımcı ol. + +##### Yardımcı olabilecek noktalar: +* Düşük seviyeli (low-level) fonksiyonların dönüş değerlerini hatırla. +* Anlam (semantic) konusunda dikkatli ol. +* Ethereum’da depolamanın (storage) nasıl çalıştığını tekrar gözden geçir. diff --git a/client/src/gamedata/tr/descriptions/levels/gatekeeper3_complete.md b/client/src/gamedata/tr/descriptions/levels/gatekeeper3_complete.md new file mode 100644 index 000000000..3dcb52703 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/gatekeeper3_complete.md @@ -0,0 +1 @@ +Tebrikler! Daha fazla bilgi için [bunu](https://web3js.readthedocs.io/en/v1.2.9/web3-eth.html?highlight=getStorageAt#getstorageat) ve [bunu](https://medium.com/loom-network/ethereum-solidity-memory-vs-storage-how-to-initialize-an-array-inside-a-struct-184baf6aa2eb) okuyabilirsin. \ No newline at end of file diff --git a/client/src/gamedata/tr/descriptions/levels/goodsamaritan.md b/client/src/gamedata/tr/descriptions/levels/goodsamaritan.md new file mode 100644 index 000000000..19b1aa800 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/goodsamaritan.md @@ -0,0 +1,7 @@ +Bu seviye; zengin, yardımsever ve kim isterse ona birkaç coin bağışlamaya hazır olan cömert ve iyi bir Samiriyeli'yi temsil ediyor. + +Peki sen… onun cüzdanındaki tüm bakiyeyi sıfırlayabilir misin? + +Yardımcı olabilecek noktalar: + +- [Solidity Custom Errors](https://blog.soliditylang.org/2021/04/21/custom-errors/) \ No newline at end of file diff --git a/client/src/gamedata/tr/descriptions/levels/goodsamaritan_complete.md b/client/src/gamedata/tr/descriptions/levels/goodsamaritan_complete.md new file mode 100644 index 000000000..c8cd54926 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/goodsamaritan_complete.md @@ -0,0 +1,3 @@ +Tebrikler! + +Solidity’deki custom errors, tıpkı fonksiyon çağrılarında olduğu gibi 4 baytlık ‘selector’ ile tanımlanır. Bu hatalar, çağrı zinciri boyunca yukarı doğru iletilir (bubbled up) ve GoodSamaritan’ın `requestDonation()` fonksiyonunda görüldüğü gibi bir try-catch bloğundaki catch tarafından yakalanana kadar ilerler. Bu yüzden hatanın doğrudan çağrı yaptığın hedef kontrat (bu durumda Wallet) tarafından atıldığını varsaymak güvenli değildir. Çağrı zincirinin daha derinlerindeki herhangi bir diğer kontrat, aynı hatayı tanımlayıp beklenmedik bir yerde fırlatabilir; mesela saldırgan kontratındaki `notify(uint256 amount)` fonksiyonunda olduğu gibi. diff --git a/client/src/gamedata/tr/descriptions/levels/higherorder.md b/client/src/gamedata/tr/descriptions/levels/higherorder.md new file mode 100644 index 000000000..6ea04f1ce --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/higherorder.md @@ -0,0 +1,9 @@ +Kuralların çiğnenmek için var olduğu, kurnaz ve cesur olanların güç kazandığı bir dünya hayal et. Gizemlerle dolu Higher Order’a hoş geldin! Burada bir hazine seni bekliyor ve başkomutan en tepedeki koltuğunda hüküm sürüyor. + +Amacın, Higher Order’ın komutanı olmak! Bol şans! + +##### Yardımcı olabilecek noktalar: +* Bazen, `calldata` güvenilmez olabilir. +* Derleyiciler sürekli gelişiyor, adeta birer uzay gemisine dönüşüyorlar. + + diff --git a/client/src/gamedata/tr/descriptions/levels/higherorder_complete.md b/client/src/gamedata/tr/descriptions/levels/higherorder_complete.md new file mode 100644 index 000000000..bd61eae5a --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/higherorder_complete.md @@ -0,0 +1,3 @@ +Higher Order meydan okumasını fethettin ve Dirty Higher Order Bits açığını kullanarak Komutan unvanını kazandın.Bu görevde, Solidity’nin derinliklerine inip byte’ları manipüle etmeyi ve fonksiyon türü kontrollerini aşmayı öğrendin. + +Bu zafer, yalnızca teknik becerilerini göstermekle kalmıyor, aynı zamanda yaratıcı ve eleştirel düşünme yeteneğini de ortaya koyuyor. \ No newline at end of file diff --git a/client/src/gamedata/tr/descriptions/levels/impersonator.md b/client/src/gamedata/tr/descriptions/levels/impersonator.md new file mode 100644 index 000000000..51b325f07 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/impersonator.md @@ -0,0 +1 @@ +SlockDotIt’in yeni ürünü **ECLocker**, IoT kapı kilitlerini Solidity akıllı kontratlarla entegre ediyor ve yetkilendirme için Ethereum ECDSA kullanıyor. Geçerli bir imza kilide gönderildiğinde sistem `Open` event’ini yayınlayıp yetkili kontrolöre kapıyı açma imkânı tanıyor. SlockDotIt, ürünü piyasaya sürmeden önce güvenliğini değerlendirmek üzere seni işe aldı. Sistemi, herkesin kapıyı açabilmesini sağlayacak şekilde ele geçirebilir misin? \ No newline at end of file diff --git a/client/src/gamedata/tr/descriptions/levels/impersonator_complete.md b/client/src/gamedata/tr/descriptions/levels/impersonator_complete.md new file mode 100644 index 000000000..4b5c83562 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/impersonator_complete.md @@ -0,0 +1,5 @@ +Tebrikler! Eliptik eğri imzalarının sırlarını başarıyla çözdün! + +[EIP-2'de](https://eips.ethereum.org/EIPS/eip-2), açıklandığı gibi, doğrulama mantığımızda şu an izin verilen `0 < s < secp256k1n` aralığı imza esnekliği (malleability) sorununa açık kapı bırakıyor. Bir imzayı alıp `s` değerini `s`’den `secp256k1n - s`’ye çevirip `v` değerini değiştirdiğinde (27 -> 28, 28 -> 27), ortaya çıkan imza aynı imzacıyı yine geri çıkaracaktır. + +Ne yaptığını tam bilmiyorsan güvenli uygulamalar kullanmak önemli. ecrecover’ı güvenli kullanmayı öğrenmek için [OpenZeppelin implementasyonuna](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/448efeea6640bbbc09373f03fbc9c88e280147ba/contracts/utils/cryptography/ECDSA.sol#L128-L154) bak. \ No newline at end of file diff --git a/client/src/gamedata/tr/descriptions/levels/magicanimalcarousel.md b/client/src/gamedata/tr/descriptions/levels/magicanimalcarousel.md new file mode 100644 index 000000000..8f7f7d51d --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/magicanimalcarousel.md @@ -0,0 +1,6 @@ +Büyülü Atlıkarınca’ya hoş geldin sevgili Anon, burada yaratıklar sonsuz bir büyü içinde dönüp durur. Bu sihirli, sınırsız dijital çarkta göz kamaştırıcı bir enerjiyle neşeyle dönüp dururlar. + +Eğlenceye katılması için bir yaratık ekle, ama kuralı unutma, yoksa oyun yarım kalır. +Bir hayvan binecekse, tekrar kontrol ettiğinde dikkat et; aynı hayvan mutlaka orada olmalı! + +Atlıkarıncanın sihirli kuralını bozabilir misin? \ No newline at end of file diff --git a/client/src/gamedata/tr/descriptions/levels/magicanimalcarousel_complete.md b/client/src/gamedata/tr/descriptions/levels/magicanimalcarousel_complete.md new file mode 100644 index 000000000..28e993efe --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/magicanimalcarousel_complete.md @@ -0,0 +1 @@ +Tebrikler, atlıkarıncanın sihirli kuralını bozdun! Düşük seviyeli veri manipülasyonu dünyasında, özellikle verileri depolama yuvalarında sıkıştırırken detayları hatırlamak hayati önem taşır. \ No newline at end of file diff --git a/client/src/gamedata/tr/descriptions/levels/magicnum.md b/client/src/gamedata/tr/descriptions/levels/magicnum.md new file mode 100644 index 000000000..25a36d0e7 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/magicnum.md @@ -0,0 +1,11 @@ +Bu seviyeyi çözmek için Ethernaut’a, `whatIsTheMeaningOfLife()` çağrısına doğru 32 baytlık sayı ile cevap veren bir `Solver` (Kontrat) vermen yeterli. + +Kolay gibi, değil mi? +Eh… bir de bir sorun var. + +Solver’ın kodu çok küçük olmalı. Çok çoooook küçük. En fazla 10 byte. + +İpucu: Belki artık Solidity derleyicisinin konforundan çıkıp bunu elle yazmanın vakti gelmiştir O_o. +Doğru duydun: Raw EVM bytecode. + +Bol şans! \ No newline at end of file diff --git a/client/src/gamedata/tr/descriptions/levels/magicnum_complete.md b/client/src/gamedata/tr/descriptions/levels/magicnum_complete.md new file mode 100644 index 000000000..86938a0a4 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/magicnum_complete.md @@ -0,0 +1,4 @@ +Tebrikler! Eğer bu seviyeyi çözdüysen, kendini Evrenin Efendisi olarak görebilirsin. + +Hadi bakalım, odadaki rastgele bir nesneyi Magnum bakışınla delip geç. Şimdi de uzaktan hareket ettirmeyi dene; telekinezi yeteneklerin çalışmaya başlamış olabilir. + diff --git a/client/src/gamedata/tr/descriptions/levels/motorbike.md b/client/src/gamedata/tr/descriptions/levels/motorbike.md new file mode 100644 index 000000000..3373fec56 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/motorbike.md @@ -0,0 +1,9 @@ +Ethernaut’un motorbike'ının yepyeni, yükseltilebilir bir motor tasarımı var. + +Bu motoru `selfdestruct` ile yok edip motorbike'ı kullanılamaz hâle getirebilir misin? + +Yardımcı olabilecek noktalar: + +- [EIP-1967](https://eips.ethereum.org/EIPS/eip-1967) +- [UUPS](https://forum.openzeppelin.com/t/uups-proxies-tutorial-solidity-javascript/7786) upgradeable (yükseltilebilir) pattern +- [Initializable](https://github.com/OpenZeppelin/openzeppelin-upgrades/blob/master/packages/core/contracts/Initializable.sol) kontratı \ No newline at end of file diff --git a/client/src/gamedata/tr/descriptions/levels/motorbike_complete.md b/client/src/gamedata/tr/descriptions/levels/motorbike_complete.md new file mode 100644 index 000000000..2bf748bb9 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/motorbike_complete.md @@ -0,0 +1,9 @@ +UUPS pattern’ini takip etmenin avantajı, çok minimal bir proxy deploy etmektir. Proxy, sadece bir depolama katmanı olarak işlev görür; yani implementasyon kontratında yapılan state değişiklikleri normalde sistemi kullanan diğer taraflar üzerinde yan etki yaratmaz, çünkü yalnızca delegatecall üzerinden mantık (logic) çalıştırılır. + +Bu, implementasyon kontratını initialize etmeden bırakmanın yaratabileceği güvenlik açıklarını göz ardı edeceğimiz anlamına gelmez. + +Bu, UUPS pattern’i yayınlandıktan sonra aylar içinde keşfedilen durumların biraz basitleştirilmiş bir versiyonudur. + +Çıkarım: implementasyon kontratlarını asla initialize edilmeden bırakma ;) + +Eğer neler olduğunu merak ediyorsan [buradan](https://forum.openzeppelin.com/t/uupsupgradeable-vulnerability-post-mortem/15680) daha fazlasını okuyabilirsin. \ No newline at end of file diff --git a/client/src/gamedata/tr/descriptions/levels/naughtcoin.md b/client/src/gamedata/tr/descriptions/levels/naughtcoin.md new file mode 100644 index 000000000..8d3081883 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/naughtcoin.md @@ -0,0 +1,6 @@ +NaughtCoin bir ERC20 token’ı ve şu anda hepsine sahipsin. Ama bir sorun var, bu token’ları yalnızca 10 yıllık bir kilitlenme süresi sonunda transfer edebileceksin. Peki, token’ları nasıl başka bir adrese aktarıp özgürce transfer edebilirsin? Bu seviyeyi tamamlamak için token bakiyeni 0’a düşür. + +  +Yardımcı olabilecek noktalar: +* [ERC20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) Spesifikasyonu +* [OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/tree/master/contracts) kod tabanı (codebase) diff --git a/client/src/gamedata/tr/descriptions/levels/naughtcoin_complete.md b/client/src/gamedata/tr/descriptions/levels/naughtcoin_complete.md new file mode 100644 index 000000000..22a9abcb5 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/naughtcoin_complete.md @@ -0,0 +1 @@ +Kendi yazmadığın bir kodu kullanırken, her şeyin nasıl bir araya geldiğini anlamak için kodu iyice tanıman her zaman iyi bir fikirdir. Bu özellikle, birden fazla iç içe import (yani import’larının da kendi import’ları olduğu durumlar) söz konusu olduğunda veya yetkilendirme kontrolleri uygularken (yani birine bir şeyi yapma izni verip vermediğinde) çok önemli hale gelir. Bu örnekte, bir geliştirici koda şöyle bir göz atıp “token transfer etmenin tek yolu transfer fonksiyonuymuş” diye düşünebilir. Ama dikkat et! Aynı işlemi gerçekleştiren farklı yollar da olabilir, sadece farklı bir şekilde uygulanmışlardır. \ No newline at end of file diff --git a/client/src/gamedata/tr/descriptions/levels/preservation.md b/client/src/gamedata/tr/descriptions/levels/preservation.md new file mode 100644 index 000000000..209768147 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/preservation.md @@ -0,0 +1,9 @@ +Bu kontrat, iki farklı zaman dilimi için iki ayrı zamanı saklamak üzere bir kütüphane kullanıyor. Kurucu fonksiyon (constructor), saklanacak her zaman için kütüphaneden iki örnek (instance) oluşturuyor. + +Bu seviyedeki amacın, sana verilen örneğin sahipliğini ele geçirmek. + +  Yardımcı olabilecek noktalar +* `delegatecall` düşük seviyeli fonksiyonunu ve nasıl çalıştığını incele: zincir üzerindeki kütüphanelere işlemleri devretmek için nasıl kullanılır ve yürütme bağlamı (execution scope) üzerinde ne gibi etkileri olur. +* `delegatecall`'ın bağlamı koruyan (context-preserving) olduğunu anlamak; yani çağrılan kodun çağıranın depolama (storage) alanı üzerinde çalıştığını unutma. +* Depolama değişkenlerinin (storage variables) nasıl saklandığını ve nasıl erişildiğini iyi anla. +* Farklı veri tipleri arasındaki tür dönüşümlerinin (casting) nasıl çalıştığını öğren. diff --git a/client/src/gamedata/tr/descriptions/levels/preservation_complete.md b/client/src/gamedata/tr/descriptions/levels/preservation_complete.md new file mode 100644 index 000000000..7c56b9168 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/preservation_complete.md @@ -0,0 +1,2 @@ +Önceki seviye olan `delegate`’ta belirtildiği gibi, kütüphaneleri çağırmak için `delegatecall` kullanmak riskli olabilir. Bu durum özellikle kendi durum (state) değişkenlerine sahip olan kontrat kütüphaneleri için geçerlidir. Bu örnek, kütüphaneler oluştururken neden `library` anahtar kelimesinin kullanılması gerektiğini gösterir, çünkü bu anahtar kelime kütüphanelerin durum değişkenlerini saklamasını ve bunlara erişmesini engeller. + diff --git a/client/src/gamedata/tr/descriptions/levels/privacy.md b/client/src/gamedata/tr/descriptions/levels/privacy.md new file mode 100644 index 000000000..ccb989c57 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/privacy.md @@ -0,0 +1,11 @@ +Bu sözleşmenin geliştiricisi, depolama alanındaki hassas bölgeleri koruma konusunda oldukça dikkatli davranmış. + +Bu seviyeyi geçmek için sözleşmeyi kilidini açman gerekiyor. + +Yardımcı olabilecek noktalar: +* Depolamanın (storage) nasıl çalıştığını anlamak +* Parametre çözümlemenin (parameter parsing) nasıl işlediğini anlamak +* Tür dönüşümlerinin (casting) nasıl yapıldığını anlamak + +İpuçları: +* MetaMask sadece bir araç — eğer sorun çıkarıyorsa başka bir aracı kullanabilirsin. Gelişmiş oynanış için Remix veya kendi web3 sağlayıcını (provider) kullanman gerekebilir. diff --git a/client/src/gamedata/tr/descriptions/levels/privacy_complete.md b/client/src/gamedata/tr/descriptions/levels/privacy_complete.md new file mode 100644 index 000000000..ea1f569f3 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/privacy_complete.md @@ -0,0 +1,3 @@ +Ethereum blok zincirinde hiçbir şey özel değildir. private anahtar kelimesi, yalnızca Solidity dilinin sunduğu yapay bir kavramdır. Web3'ün `getStorageAt(...)` fonksiyonu, depolamadaki herhangi bir veriyi okumak için kullanılabilir. Yine de istediğin bilgiyi doğru şekilde okumak bazen zor olabilir çünkü derleyici, depolama alanını mümkün olduğunca sıkıştırmak (optimize etmek) için çeşitli kurallar ve teknikler uygular. + +Bu seviyede gördüklerinden daha karmaşık örneklerle pek karşılaşmazsın. Daha fazlasını öğrenmek istersen, “Darius” tarafından yazılan şu harika makaleye göz atabilirsin: [How to read Ethereum contract storage](https://medium.com/aigang-network/how-to-read-ethereum-contract-storage-44252c8af925) diff --git a/client/src/gamedata/tr/descriptions/levels/puzzle_wallet.md b/client/src/gamedata/tr/descriptions/levels/puzzle_wallet.md new file mode 100644 index 000000000..d01113738 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/puzzle_wallet.md @@ -0,0 +1,18 @@ +Günümüzde DeFi işlemleri için ödeme yapmak neredeyse imkânsız hâl aldı. + +Bir grup arkadaş, birden fazla işlemi tek bir işlemde batchleyerek maliyeti biraz düşürmenin yolunu buldu ve bunu yapan bir akıllı kontrat geliştirdiler. + +Bu kontratın kodunda hata olması durumunda güncellenebilir olmasını istediler ve ayrıca grubun dışındakilerin kullanmasını engellemek istediler. Bu nedenle oylama yaptılar ve sisteme iki özel rol atadılar: +Admin, akıllı kontratın mantığını (logic) güncelleme yetkisine sahip. +Owner, Kontratı kullanmaya izin verilen adreslerin whitelist’ini kontrol ediyor. +Kontratlar dağıtıldı ve grup whitelist’e eklendi. Herkes madencilere karşı zaferlerini kutladı. + +Fakat bilmedikleri şey, öğle yemeği paraları tehlikedeydi... + +  +Bu cüzdanı ele geçirip proxy’nin admini olmalısın. + +  +Yardımcı olabilecek noktalar: +* `delegatecall`'ın nasıl çalıştığını ve bir `delegatecall` sırasında `msg.sender` ile `msg.value`'ın nasıl davrandığını anla. +* Proxy pattern’leri ve bunların storage (depolama) değişkenlerini nasıl yönettiğini öğren. diff --git a/client/src/gamedata/tr/descriptions/levels/puzzle_wallet_complete.md b/client/src/gamedata/tr/descriptions/levels/puzzle_wallet_complete.md new file mode 100644 index 000000000..61fdf0ee1 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/puzzle_wallet_complete.md @@ -0,0 +1,7 @@ +Bir dahaki sefere, o arkadaşlar bir kontrata para yatırmadan önce mutlaka bir denetim talep edecekler. Tebrikler! + +Proxy kontratları kullanmak, yükseltilebilirlik özellikleri kazandırmak ve dağıtım sırasında gaz maliyetini düşürmek için sıkça tavsiye edilir. Ancak, geliştiricilerin depolama çakışmalarına yol açmamaya dikkat etmesi gerekir, bu seviye de bunu gözler önüne seriyor. + +Ayrıca, ETH tüketen işlemler üzerinde iterasyon yapmak, doğru şekilde yönetilmezse sorunlara yol açabilir. ETH harcansa bile `msg.value` değeri aynı kalır, bu yüzden geliştirici her iterasyonda kalan gerçek miktarı manuel olarak takip etmelidir. Bu durum, birden çok `delegatecall` içeren çoklu çağrı (multi-call) deseninde de sorun yaratabilir; kendi başına güvenli görünen bir fonksiyona yapılan birden fazla `delegatecall`, istem dışı ETH transferlerine yol açabilir çünkü `delegatecall` gönderilen orijinal `msg.value` değerini korur. + +Hazır olduğunda bir sonraki seviyeye geçebilirsin! diff --git a/client/src/gamedata/tr/descriptions/levels/recovery.md b/client/src/gamedata/tr/descriptions/levels/recovery.md new file mode 100644 index 000000000..526e38b8a --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/recovery.md @@ -0,0 +1,4 @@ + +Bir kontrat geliştiricisi, oldukça basit bir token fabrikası kontratı oluşturdu. Herkes kolayca yeni token’lar oluşturabiliyor. İlk token kontratını dağıttıktan sonra geliştirici, biraz daha token almak için `0.001` ether gönderdi. Ancak, daha sonra sözleşme adresini kaybetti. + +Bu seviyeyi tamamlamak için, o kayıp sözleşme adresindeki `0.001` ether’i geri alman veya kurtarman gerekiyor. diff --git a/client/src/gamedata/tr/descriptions/levels/recovery_complete.md b/client/src/gamedata/tr/descriptions/levels/recovery_complete.md new file mode 100644 index 000000000..e4e85f046 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/recovery_complete.md @@ -0,0 +1,8 @@ + +Sözleşme adresleri deterministiktir ve `keccak256(address, nonce)` formülüyle hesaplanır. Burada `address`, işlemi veya sözleşmeyi oluşturan Ethereum adresini, `nonce` ise oluşturulan sözleşme sayısını (ya da normal işlemler için işlem nonce’unu) ifade eder. + +Bu nedenle, biri özel anahtarı olmayan, önceden belirlenmiş bir adrese ether gönderebilir ve daha sonra o adreste bir sözleşme oluşturarak gönderilen ether’i geri alabilir. Bu yöntem, özel anahtar tutmadan ether saklamanın sezgisel olmayan ve biraz gizemli (ve tehlikeli) bir yoludur. + +Martin Swende’nin bu konudaki olası kullanım alanlarını anlattığı ilginç bir [blog yazısı](https://swende.se/blog/Ethereum_quirks_and_vulns.html) mevcut. + +Bu tekniği kullanmayı düşünüyorsan, nonce’u kaçırmadığından emin ol, aksi takdirde fonların sonsuza kadar kaybolur. \ No newline at end of file diff --git a/client/src/gamedata/tr/descriptions/levels/shop.md b/client/src/gamedata/tr/descriptions/levels/shop.md new file mode 100644 index 000000000..14e2a80fe --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/shop.md @@ -0,0 +1,5 @@ +Mağazadan ürünü, istenen fiyattan daha ucuza alabilir misin? + +##### Yardımcı olabilecek noktalar: +* `Shop` sözleşmesi, bir `Buyer` tarafından kullanılmayı bekliyor +* view fonksiyonlarının kısıtlamalarını anlamak diff --git a/client/src/gamedata/tr/descriptions/levels/shop_complete.md b/client/src/gamedata/tr/descriptions/levels/shop_complete.md new file mode 100644 index 000000000..3307cba60 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/shop_complete.md @@ -0,0 +1,3 @@ +Sözleşmeler, diğer sözleşmelerin görebildiği verileri istediği gibi değiştirebilir. + +Dışarıdan gelen ve güvenilmeyen sözleşme mantığına dayanarak state’i değiştirmek güvenli değildir. \ No newline at end of file diff --git a/client/src/gamedata/tr/descriptions/levels/stake.md b/client/src/gamedata/tr/descriptions/levels/stake.md new file mode 100644 index 000000000..470d87073 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/stake.md @@ -0,0 +1,13 @@ +Stake kontratı, native ETH ve ERC20 WETH ile staking için güvenlidir; her iki token da 1:1 değer oranına sahiptir. Peki, kontratı boşaltabilir misin? + +Bu seviyeyi tamamlamak için kontrat durumu aşağıdaki şartları sağlamalı: + +- `Stake` kontratının ETH bakiyesi 0’dan büyük olmalı. +- `totalStaked`, `Stake` kontratının ETH bakiyesinden büyük olmalı. +- Bir staker olmalısın. +- Stake edilmiş bakiyen 0 olmalı. + +Yardımcı olabilecek noktalar: + +- [ERC-20](https://github.com/ethereum/ercs/blob/master/ERCS/erc-20.md) spesifikasyonu. +- [OpenZeppelin kontratları](https://github.com/OpenZeppelin/openzeppelin-contracts) diff --git a/client/src/gamedata/tr/descriptions/levels/stake_complete.md b/client/src/gamedata/tr/descriptions/levels/stake_complete.md new file mode 100644 index 000000000..ffeddac49 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/stake_complete.md @@ -0,0 +1,5 @@ +Tebrikler, `Stake` makinesini kırdın! + +Dış kontratlara yapılan low-level çağrılarda, çağrının revert edip etmediğini anlamak için dönüş değerlerini doğru şekilde doğrulamak çok önemlidir. + +Daha fazla bilgi için [EEA EthTrust [S] Check External Calls Return](https://entethalliance.github.io/eta-registry/security-levels-spec.html#req-1-check-return) gereksinimine bakabilir ve dış ERC-20 tokenlarıyla etkileşimde her zaman [SafeERC20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol) kullanabilirsin. \ No newline at end of file diff --git a/client/src/gamedata/tr/strings.json b/client/src/gamedata/tr/descriptions/levels/strings.json similarity index 100% rename from client/src/gamedata/tr/strings.json rename to client/src/gamedata/tr/descriptions/levels/strings.json diff --git a/client/src/gamedata/tr/descriptions/levels/switch.md b/client/src/gamedata/tr/descriptions/levels/switch.md new file mode 100644 index 000000000..4440bf8d8 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/switch.md @@ -0,0 +1,4 @@ +Sadece düğmeye basman gerekiyor. O kadar da zor olamaz, değil mi? + +##### Yardımcı olabilecek noktalar: +`CALLDATA`'nın nasıl encode edildiğini anlamak \ No newline at end of file diff --git a/client/src/gamedata/tr/descriptions/levels/switch_complete.md b/client/src/gamedata/tr/descriptions/levels/switch_complete.md new file mode 100644 index 000000000..0282e2317 --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/switch_complete.md @@ -0,0 +1 @@ +`CALLDATA` içindeki pozisyonları varsaymak hatalara yol açabilir, özellikle de sabitlenmiş `CALLDATA` konumları kullanıldığında. diff --git a/client/src/gamedata/tr/descriptions/levels/unstoppable.md b/client/src/gamedata/tr/descriptions/levels/unstoppable.md new file mode 100644 index 000000000..e02c570df --- /dev/null +++ b/client/src/gamedata/tr/descriptions/levels/unstoppable.md @@ -0,0 +1,5 @@ +Bir milyon token bakiyesi olan bir borç havuzu var ve ücretsiz flash loan (anlık kredi) sunuyor. + +Keşke havuza saldırıp flash loan vermesini durdurmanın bir yolu olsaydı... + +Başlangıçta hesabında 100 token ile başlıyorsun. \ No newline at end of file