Information on 2022 TinyMan Hack

I wanted to start a thread with information on the January 2022 TinyMan hack. I hadn’t seen any updates on this in a while, but I read the DOJ recently caught a Bitcoin hacker and seized over $3B in stolen assets.

Here is at least one of the TinyMan hackers addresses.

MNN5MB3E7JSJPA6FRMCKUTK5V77GSJIALVWVCBXFZLEVAUEY5FUPGJUDPE

The exploit was carried out on several pools and is viewable in the transaction logs. The address was funded by a Binance account, so Binance would likely have the hackers information.

Please feel free to share any updates on prosecution efforts or any other information relating to the hack.

@taylan

1 Like

Good info, thanks. Hopefully the Foundation will use this info.

1 Like

An additional ~5,600 Algo were siphoned from the Choice-Algo pool on TinyMan v1.0 in October. The attacker used an address funded with Algo from OKEX, which would have the hacker’s identity. The attacker also stole ~22,000 USDC from the TinyMan v1.0 USDC-ALGO pool.

It appears likely this hack was completed by someone with inside knowledge of the TinyMan v1.0 protocol. It’s important that @taylan address this issue because the TinyMan v1.0 protocol continues to be drained of funds and contains significant value. For example, the TinyMan v1.0 USDC-Algo pool still contains ~37,000 Algo. A strategy needs to be put together to recover existing funds from the TinyMan v1.0 protocol, which requires an independent audit.

Recent evidence has come to my attention regarding the TinyMan hack. As it turns out, TinyMan never provided Choice Coin users compensation for the hack as promised through their compensation program. I am working on solutions now. I included it in a Draft Report regarding the TinyMan Hack with proposed solutions for collaboration between PeraWallet, TinyMan, and Choice Coin.

1 Like

Update

The TinyMan team and Hipo Labs team are still silent on a resolution. The two teams have completely failed to follow through as promised regarding the TinyMan compensation program for the v1.0 hack. They have continuously made false and misleading claims to users and have acted with complete disregard for ethics and the law.

I strongly advise against using the TinyMan platform, as security risks and illegal activity are on-going within the TinyMan protocol.

I wanted to include the TEAL code from the most recent attack on the v1.0 code.

Hack TXID: MTBGLTBMYCM7EUSFY6K7L6ONQ7AQN3V7C2NT3TZHEU3WXD2QDXVA
Pool Address: 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
Hacker Address: KFPIZAUTTOXIN5DGDGMMNSPVXYD6YGC7TEDPKZANIXYWBIFB445OTEY4N4
Hacker Address Funding TXID: UWW5KSPSPGV3J5XURM2SQFEKO4UYAVEHLTCSHWMVXSTEW2XZDCFA

Code:

#pragma version 4
	intcblock 1 0 0 3 4 297995609 5 6
	intc 5 // 297995609
	intc_2 // 0
	>
	assert
	txn CloseRemainderTo // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ
	global ZeroAddress
	==
	assert
	txn AssetCloseTo // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ
	global ZeroAddress
	==
	assert
	txn RekeyTo // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ
	global ZeroAddress
	==
	assert
	global GroupSize // size=3
	intc_0 // 1
	>
	assert
	gtxn 1 Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	==
	assert
	gtxn 1 TypeEnum
	intc 7 // 6
	==
	assert
	gtxn 1 ApplicationID // id=350338509
	pushint 350338509
	==
	assert
	gtxn 1 OnCompletion
	intc_0 // 1
	==
	gtxn 1 NumAppArgs // index=1
	intc_3 // 3
	==
	&&
	gtxna 1 ApplicationArgs 0 // arg=72656465656d
	pushbytes 0x626f6f747374726170 // "bootstrap"
	==
	&&
	bnz label1
	gtxn 1 OnCompletion
	intc_1 // 0
	==
	assert
	gtxn 1 NumAppArgs // index=1
	pushint 2
	==
	gtxna 1 ApplicationArgs 0 // arg=72656465656d
	pushbytes 0x73776170 // "swap"
	==
	&&
	bnz label2
	gtxn 1 NumAppArgs // index=1
	intc_0 // 1
	==
	assert
	gtxna 1 ApplicationArgs 0 // arg=72656465656d
	pushbytes 0x6d696e74 // "mint"
	==
	bnz label3
	gtxna 1 ApplicationArgs 0 // arg=72656465656d
	pushbytes 0x6275726e // "burn"
	==
	bnz label4
	gtxna 1 ApplicationArgs 0 // arg=72656465656d
	pushbytes 0x72656465656d // "redeem"
	==
	bnz label5
	gtxna 1 ApplicationArgs 0 // arg=72656465656d
	pushbytes 0x66656573 // "fees"
	==
	bnz label6
	err
label1:
	intc 6 // 5
	intc 4 // 4
	intc_2 // 0
	intc_1 // 0
	==
	select
	global GroupSize // size=3
	==
	assert
	gtxna 1 ApplicationArgs 1
	btoi
	intc 5 // 297995609
	==
	gtxna 1 ApplicationArgs 2
	btoi
	intc_2 // 0
	==
	&&
	assert
	gtxn 2 Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	==
	assert
	gtxn 2 TypeEnum
	intc_3 // 3
	==
	assert
	gtxn 2 ConfigAsset // id=0
	intc_1 // 0
	==
	assert
	gtxn 2 ConfigAssetTotal // total=0.
	intc_1 // 0
	~
	==
	assert
	gtxn 2 ConfigAssetDecimals // dec=0
	intc 7 // 6
	==
	assert
	gtxn 2 ConfigAssetDefaultFrozen // default=false
	intc_1 // 0
	==
	assert
	gtxn 2 ConfigAssetUnitName // 
	pushbytes 0x544d31504f4f4c // "TM1POOL"
	==
	assert
	gtxn 2 ConfigAssetName // 
	substring 0 13
	pushbytes 0x54696e796d616e20506f6f6c20 // "Tinyman Pool "
	==
	assert
	gtxn 2 ConfigAssetURL // 
	pushbytes 0x68747470733a2f2f74696e796d616e2e6f7267 // "https://tinyman.org"
	==
	assert
	gtxn 2 ConfigAssetManager
	global ZeroAddress
	==
	assert
	gtxn 2 ConfigAssetReserve
	global ZeroAddress
	==
	assert
	gtxn 2 ConfigAssetFreeze
	global ZeroAddress
	==
	assert
	gtxn 2 ConfigAssetClawback
	global ZeroAddress
	==
	assert
	gtxn 3 Sender
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	==
	assert
	gtxn 3 TypeEnum
	intc 4 // 4
	==
	assert
	gtxn 3 XferAsset
	intc 5 // 297995609
	==
	assert
	gtxn 3 AssetReceiver
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	==
	assert
	gtxn 3 AssetAmount
	intc_1 // 0
	==
	assert
	intc_2 // 0
	intc_1 // 0
	!=
	bnz label7
	gtxn 1 Fee // 0.001000
	gtxn 2 Fee // 0.001000
	+
	gtxn 3 Fee
	+
	store 1
	b label8
label7:
	gtxn 4 Sender
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	==
	assert
	gtxn 4 TypeEnum
	intc 4 // 4
	==
	assert
	gtxn 4 XferAsset
	intc_2 // 0
	==
	assert
	gtxn 4 AssetReceiver
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	==
	assert
	gtxn 4 AssetAmount
	intc_1 // 0
	==
	assert
	gtxn 1 Fee // 0.001000
	gtxn 2 Fee // 0.001000
	+
	gtxn 3 Fee
	+
	gtxn 4 Fee
	+
	store 1
	b label8
label3:
	global GroupSize // size=3
	intc 6 // 5
	==
	assert
	gtxna 1 Accounts 1
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	!=
	assert
	gtxna 1 Accounts 1
	gtxn 4 AssetReceiver
	==
	assert
	gtxn 2 Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	!=
	assert
	gtxn 2 AssetReceiver // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	==
	assert
	gtxn 3 Sender
	gtxn 2 Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	==
	assert
	gtxn 3 AssetReceiver
	gtxn 3 Receiver
	gtxn 3 TypeEnum
	intc_0 // 1
	==
	select
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	==
	assert
	gtxn 4 Sender
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	==
	assert
	gtxn 4 AssetReceiver
	gtxn 2 Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	==
	assert
	gtxn 1 Fee // 0.001000
	gtxn 4 Fee
	+
	store 1
	b label8
label4:
	global GroupSize // size=3
	intc 6 // 5
	==
	assert
	gtxna 1 Accounts 1
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	!=
	assert
	gtxna 1 Accounts 1
	gtxn 2 AssetReceiver // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ
	==
	assert
	gtxn 3 AssetReceiver
	gtxn 3 Receiver
	gtxn 3 TypeEnum
	intc_0 // 1
	==
	select
	gtxna 1 Accounts 1
	==
	assert
	gtxn 2 Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	==
	assert
	gtxn 2 AssetReceiver // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ
	gtxn 4 Sender
	==
	assert
	gtxn 3 Sender
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	==
	assert
	gtxn 3 AssetReceiver
	gtxn 3 Receiver
	gtxn 3 TypeEnum
	intc_0 // 1
	==
	select
	gtxn 4 Sender
	==
	assert
	gtxn 4 Sender
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	!=
	assert
	gtxn 4 AssetReceiver
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	==
	assert
	gtxn 1 Fee // 0.001000
	gtxn 2 Fee // 0.001000
	+
	gtxn 3 Fee
	+
	store 1
	b label8
label2:
	global GroupSize // size=3
	intc 4 // 4
	==
	assert
	gtxna 1 Accounts 1
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	!=
	assert
	gtxn 2 Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	gtxna 1 Accounts 1
	==
	assert
	gtxn 2 Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	!=
	assert
	gtxn 3 Sender
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	==
	assert
	gtxn 2 AssetReceiver // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ
	gtxn 2 Receiver // KFPIZAUTTOXIN5DGDGMMNSPVXYD6YGC7TEDPKZANIXYWBIFB445OTEY4N4
	gtxn 2 TypeEnum
	intc_0 // 1
	==
	select
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	==
	assert
	gtxn 3 AssetReceiver
	gtxn 3 Receiver
	gtxn 3 TypeEnum
	intc_0 // 1
	==
	select
	gtxn 2 Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	==
	assert
	gtxn 1 Fee // 0.001000
	gtxn 3 Fee
	+
	store 1
	b label8
label5:
	global GroupSize // size=3
	intc_3 // 3
	==
	assert
	gtxna 1 Accounts 1
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	!=
	assert
	gtxn 2 AssetReceiver // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ
	gtxn 2 Receiver // KFPIZAUTTOXIN5DGDGMMNSPVXYD6YGC7TEDPKZANIXYWBIFB445OTEY4N4
	gtxn 2 TypeEnum
	intc_0 // 1
	==
	select
	gtxna 1 Accounts 1
	==
	assert
	gtxn 1 Fee // 0.001000
	gtxn 2 Fee // 0.001000
	+
	store 1
	b label8
label6:
	global GroupSize // size=3
	intc_3 // 3
	==
	assert
	gtxn 1 Fee // 0.001000
	gtxn 2 Fee // 0.001000
	+
	store 1
	b label8
label8:
	gtxn 0 Sender // KFPIZAUTTOXIN5DGDGMMNSPVXYD6YGC7TEDPKZANIXYWBIFB445OTEY4N4
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	!=
	assert
	gtxn 0 Receiver // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	txn Sender // 4ADBL4JU6XRWT2DLWMNTQ7V7GLQUVVUQJ5NDWUNGXAJPRW3JGZ7HJUSC4I
	==
	assert
	gtxn 0 Amount // 0.002000
	load 1
	>=
	return

Unfortunately, I still have ongoing security concerns regarding TEAL due to the lack of logical structure in the languages design. Typically, programming languages follow logical structures and object oriented methodologies. The problem with TEAL is that it appears to be randomly arranged sequences of bytecode. But, the TEAL documentation fails to explain the stack, any software execution methods, or the basic structure of the language.

TEAL uses assembly language syntax - it is not object oriented. That’s probably why you’re having trouble understanding it.

1 Like

That’s true. I am not familiar with assembly language syntax. But, still TEAL seams to be very different than other examples of als on the Internet. There needs to be documentation for the basic structure and purpose of the parts of the code for developers to be able to learn and understand it.

Update

One of the malicious hacker addresses is still active and using several applications on Algorand.

KFPIZAUTTOXIN5DGDGMMNSPVXYD6YGC7TEDPKZANIXYWBIFB445OTEY4N4